Ideas about working around undefined

I’m not a javascript hero and Meteor has been my initiation into javascript, apart from jquery copy pasting done in the past.

So, I am wondering how people are dealing wih undefined, especially when working with nested objects. (No, I don’t want to hear about coffeescript, thank you.)

I’m currently using:

/*
  for something like this:
  foo = {
    bar: {
      baz: 'value'
    }
  };
*/
return foo && foo.bar && foo.bar.baz || 'no baz found';

Ideally, I’d like to be able to:

  • Just return foo.bar.baz without the prior existence checks
  • And return a default value if that’s not defined

Even better would be

  • Return a default value that I can configure per namespace just once
  • eg no bar found
1 Like

not a javascript geek myself, but i think you can try this:

return ( foo && foo.bar && foo.bar.baz ) ? foo.bar.baz : 'no baz found';

ternary operator

CONDITION ? RESULT_IF_IS_TRUE : RESULT_IF_IS_FALSE;

@narven thanks, but it is not much different than what I’m doing for a check and in fact I’m using ternary operators as shorthand alternative to if's. Yet, I want to be able to directly call foo.bar.baz without the ceremony or at least with as little as possible.

you can implement Object.prototype.safeGet method:

return foo.safeGet('bar.baz', 'no baz found');
1 Like

Yep, I found solutions very similar to that and this but what I don’t like about them is the usage of a String for invocation. It is both slow and prone to errors.

In Groovy there is a null safe dereference operator which looks like foo?.bar?.baz
and returns a falsey value in case any dereference failed. I miss this sugar syntax in JS, but your implementation is quite neat and efficient. I would keep it simple.

Oh yes I loved that especially when I used it for templating in the play framework back in the day.

I’ve actually hadn’t given this problem much thought until today and I’m thinking, perhaps the best engineering for these cases is to create self aware getters for parent objects, but then it means I’m getting into object oriented territory, which I don’t want to go back to after working with javascript’s declarative and functional style.

Oh well, I guess I can’t have the cake and eat it, too :expressionless:

CoffeeScript has the ? operator:

return if foo?.bar?.baz? then foo.bar.faz else 'no baz found'

It’s an MDG-maintained package: meteor add coffeescript

2 Likes

I’m going to give you the null answer: I use the same syntax as you.

There’s an argument to be made that these types of checks are cumbersome but necessary. Our programs simply need to take into account the null case. Though, I would agree that a shorthand would be helpful.

There’s only verbose checks like you have already. ES6 won’t help either, but ES7 might help if they can work out what they want to do

https://esdiscuss.org/topic/existential-operator-null-propagation-operator

Ah the last comment just stabs me in the hart:

If a language has to have such an operator, it should at least be very explicit and as inconvenient as bearable.

Well, I already said

No, I don’t want to hear about coffeescript, thank you.

But nice effort trying to sneak in the coffeescript card, well played my friend :wink:

1 Like

@energistic I’m beginning to think I should accept this as you said and move on. After all, engineering is all about covering the foreseeable ground, not walking around it, right?

Meteor has an undocumented method _get. First argument takes a variable any after should be strings.

var baz = Meteor._get(foo, 'bar', 'baz');
2 Likes

I would still say use coffescript or just take some example coffee use, put it to coffee2js and make your own global function from it.

1 Like

Whaaa!

There is also Meteor._ensure whaaa!!!

1 Like

It’s even simpler than that with CoffeeScript. No return/if/then/else necessary:

foo?.bar?.baz ? 'no baz found'

return Spacebars.dot(foo, "bar", "baz") || 'no baz found';

The beauty of using Spacebars.dot() over Meteor._get() is that it also works with functions:

var foo = {
    bar: function () {
      return { baz: "value"}
    }
  };

console.log(Spacebars.dot(foo, "bar", "baz") || "No baz exists")  // "value"
console.log(Meteor._get(foo, "bar", "baz") || "No baz exists")  // "No baz exists"

Hah, rather interesting and useful.

I seriously do wonder why such gems are hidden and left undocumented. Not everyone can find the time to browse the sources and discover these.

It is not an excuse to say “read the sources” or “the sources are well documented” and I strongly believe meteor documentation, although kind of sufficient compared to some other libraries and frameworks, is far from complete and approachable.

I remember @sashko starting a thread way back when about improving the documentation with a drop in comments system so at least the community would be able to contribute without the hassles of official PR’s.

Now I know I digress, but I guess this is more important a topic than finding lazy ways of accessing nested properties :smile:

Coffeescript is awesome. Don’t be scared. Embrace. Or you can write Roller Coaster Tycoon in assembly. Up to you. :wink:

1 Like