JavaScript Access nested property, in a safe way [duplicate] access nested property javascript,javascript access nested property by string,

I have json based data structure with objects containing nested objects. In order to access a particular data element I have been chaining references to object properties together. For example:

var a = b.c.d;

If b or b.c is undefined, this will fail with an error. However, I want to get a value if it exists otherwise just undefined. What is the best way to do this without having to check that every value in the chain exists?

I would like to keep this method as general as possible so I don't have to add huge numbers of helper methods like:

var a = b.getD();

or

var a = helpers.getDFromB(b);

I also want to try to avoid try/catch constructs as this isn't an error so using try/catch seems misplaced. Is that reasonable?

Any ideas?

Answer:1

Standard approach:

var a = b && b.c && b.c.d && b.c.d.e;

is quite fast but not too elegant (especially with longer property names).

Using functions to traverse JavaScipt object properties is neither efficient nor elegant.

Try this instead:

try { var a = b.c.d.e; } catch(e){}

in case you are certain that a was not previously used or

try { var a = b.c.d.e; } catch(e){ a = undefined; }

in case you may have assigned it before.

This is probably even faster that the first option.

Answer:2

If you would like to have a dynamic access with irregular number of properties at hand, in ES6 you might easily do as follows;

function getNestedValue(o,...a){
  var val = o;
  for (var prop of a) val = typeof val === "object" &&
                                   val !== null     &&
                                   val[prop] !== void 0 ? val[prop]
                                                        : undefined;
  return val;
}
var obj = {a:{foo:{bar:null}}};
console.log(getNestedValue(obj,"a","foo","bar"));
console.log(getNestedValue(obj,"a","hop","baz"));
Answer:3

probably it's may be simple:

let a = { a1: 11, b1: 12, c1: { d1: 13, e1: { g1: 14 }}}
console.log((a || {}).a2); => undefined
console.log(((a || {}).c1 || {}).d1) => 13

and so on.

Answer:4

Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.

In ES6 we can get nested property from an Object like below code snippet.

const myObject = {
    a: {
      b: {
        c: {
          d: 'test'
        }
      }
    },
    c: {
      d: 'Test 2'
    }
  },

  isObject = obj => obj && typeof obj === 'object',

  hasKey = (obj, key) => key in obj;



function nestedObj(obj, property, callback) {
  return property.split('.').reduce((item, key) => {
    if (isObject(item) && hasKey(item, key)) {
      return item[key];
    }
    return typeof callback != undefined ? callback : undefined;
  }, obj);
}

console.log(nestedObj(myObject, 'a.b.c.d')); //return test


console.log(nestedObj(myObject, 'a.b.c.d.e')); //return undefined


console.log(nestedObj(myObject, 'c.d')); //return Test 2


console.log(nestedObj(myObject, 'd.d', false)); //return false


console.log(nestedObj(myObject, 'a.b')); //return {"c": {"d": "test"}}
Answer:5

An old question, and now days we have Typescript projects so often that this question seems irrelevant, but I got here searching for the same thing, so I made a simple function to do it. Your thoughts about not using try/catch is too strict for my taste, after all the seek for undefined.x will cause an error anyway. So with all that, this is my method.

function getSafe (obj, valuePath) {
    try { return eval("obj." + valuePath); } 
    catch (err) { return null; }
}

To use this we have to pass the object. I tried to avoid that, but there was not other way to get scope into it from another function (there is a whole bunch of questions about this in here). And a small test set to see what we get:

let outsideObject = {
    html: {
        pageOne: {
            pageTitle: 'Lorem Ipsum!'
        }
    }
};
function testme() {  
    let insideObject = { a: { b: 22 } };
    return {
        b: getSafe(insideObject, "a.b"),       // gives: 22
        e: getSafe(insideObject, "a.b.c.d.e"), // gives: null
        pageTitle: getSafe(outsideObject, "html.pageOne.pageTitle"),     // gives: Lorem Ipsum!
        notThere: getSafe(outsideObject, "html.pageOne.pageTitle.style") // gives: undefined
    }
}
testme(); 

UPDATE: Regarding the use of eval I think that eval is a tool to use carefully and not the devil itself. In this method, the user does not interfere with eval since it is the developer that is looking for a property by its name.

Answer:6

If you care about syntax, here's a cleaner version of Hosar's answer:

function safeAccess(path, object) {
  if (object) {
    return path.reduce(
      (accumulator, currentValue) => (accumulator && accumulator[currentValue] ? accumulator[currentValue] : null),
      object,
    );
  } else {
    return null;
  }
}
Answer:7

I have similar code like below and I want If I clicked in Child Div then Parent Div click event should not trigger. <div class="parentDiv" (click)="parentDiv()"> <div class="childDiv" (...

I have similar code like below and I want If I clicked in Child Div then Parent Div click event should not trigger. <div class="parentDiv" (click)="parentDiv()"> <div class="childDiv" (...

I have the following code: Html <div ng-controller="MyCtrl"> {{message}}! <button ng-click="changeMessage()">change Message</button> </div> AngularJs var myApp = ...

I have the following code: Html <div ng-controller="MyCtrl"> {{message}}! <button ng-click="changeMessage()">change Message</button> </div> AngularJs var myApp = ...

  1. angularjs uncaught referenceerror require is not defined
  2. angularjs uncaught referenceerror is not defined
  3. angularjs uncaught referenceerror angular is not defined
  4. angularjs uncaught referenceerror exports is not defined
  5. angularjs uncaught referenceerror $filter is not defined
  6. angularjs uncaught referenceerror moment is not defined

I want to pass an Id when I open a model from bootstrap. I have a table and want to click on the row to do this. I am using master-pages and I am loading the jquery and bootstrap at the end of the ...

I want to pass an Id when I open a model from bootstrap. I have a table and want to click on the row to do this. I am using master-pages and I am loading the jquery and bootstrap at the end of the ...

Having a weird issue, on Windows 10 in the screen settings on some laptops the default value (the recommended) is 125% so when opening a web page everything is to big because the page was build for ...

Having a weird issue, on Windows 10 in the screen settings on some laptops the default value (the recommended) is 125% so when opening a web page everything is to big because the page was build for ...

  1. windows screen scale
  2. windows 10 screen scale
  3. windows scale screen size
  4. windows 7 screen scale
  5. windows get screen scale
  6. windows 10 scale screen size
  7. windows 10 change screen scale
  8. windows 7 scale screen resolution
  9. windows xp scale screen
  10. windows 10 lock screen scale
  11. windows 10 adjust screen scale
  12. windows 10 full screen scale
  13. windows 10 grayscale screen
  14. windows 10 qt_auto_screen_scale_factor