3

doing the following is risking an exception 'there is no Bar on undefined'

var obj = o.Foo.Bar

the only way i can think of doing above safely :

var obj = (o && o.Foo && o.Foo.Bar ) ? o.Foo.Bar : null;

or putting the entire thing in try/catch which is not an option in most cases for me.. and results in more code if i want a different thing to happen depending on which property is missing.

is there a good concise way to perform this assignment safely?

** update **

tweaked @techfoobar's answer

function resolve(obj, propertyPath) {
    if (!propertyPath) return;

    var props = propertyPath.split('.');
    var o = obj;
    for(var i in props) {
        o = o[props[i]];
        if(!o) return false;
    }
    return o;
}

var res = resolve(obj, 'ApiResponse.CommandResponse');
if (res){
   for (var i in res){

seems like as good as it's going to get...

Sonic Soul
  • 23,855
  • 37
  • 130
  • 196
  • possible duplicate of [What's the simplest approach to check existence of deeply-nested object property in JavaScript?](http://stackoverflow.com/questions/6927242/whats-the-simplest-approach-to-check-existence-of-deeply-nested-object-property) -- have a look at the second answer. – Felix Kling May 18 '13 at 17:15
  • @FelixKling that one recommends try/catch :( is that the only option in node.js as well? – Sonic Soul May 18 '13 at 17:17
  • The second answer (http://stackoverflow.com/a/6927402/218196) provides a function which checks the existence of nested properties. It's either that or try-catch. – Felix Kling May 18 '13 at 17:19

1 Answers1

0

One way is moving that into a function that you can re-use in multiple scenarios regardless of the depth you need to go:

function resolve(_root) {
   if(arguments.length == 1) return _root; // in case only root is passed
   var o = _root;
   for(var i=1; i<arguments.length; i++) {
      o = o[arguments[i]];
      if(!o) return undefined;
   }
   return o;
}

For an example object var o = {x: {y:10, c:{h: 20}}};, you can use it like:

resolve(o, 'x') gives {y:10, c:{h: 20}}

resolve(o, 'x', 'c', 'h') gives 20

whereas

resolve(o, 'x', 'c', 'boo') gives undefined

In your case, you can use it like:

var obj = resolve(o, 'Foo', 'Bar');
if(obj !== undefined) { // successfully resolved
   // do stuff ...
}
techfoobar
  • 65,616
  • 14
  • 114
  • 135