JavaScript, an elegant way to check the properties of nested objects for null / undefined

The "problem" that I have from time to time is that I have an object, for example, user = {} and when using the application this is filled. Say somewhere after an AJAX call or something that I do this:

 user.loc = { lat: 50, long: 9 } 

Elsewhere I want to check if user.loc.lat .

 if (user.loc.lat) { // do something } 

If it does not exist, it will result in an error. If user.loc.lat not undefined , user.loc course also not undefined .

 "Cannot read property 'lat' of null" - Dev Tools error 

This means that I need to check it like this:

 if (user.loc) { if (user.loc.lat) { // do something } } 

or

 if (user.loc && user.loc.lat) { // do something } 

It's not very pretty, and the larger my objects, the worse it gets - obviously (imagine 10 levels of nesting). It seems to me that if(user.loc.lat) does not just return false if user.loc not undefined .

What is the ideal way to check such situations?

+81
javascript object javascript-objects
May 22 '14 at 13:55
source share
4 answers

You can use the utility function as follows:

 get = function(obj, key) { return key.split(".").reduce(function(o, x) { return (typeof o == "undefined" || o === null) ? o : o[x]; }, obj); } 

Using:

  get(user, 'loc.lat') // 50 get(user, 'loc.foo.bar') // undefined 

Or, to check only if a property exists without getting its value:

 has = function(obj, key) { return key.split(".").every(function(x) { if(typeof obj != "object" || obj === null || ! x in obj) return false; obj = obj[x]; return true; }); } if(has(user, 'loc.lat')) ... 
+116
May 22 '14 at 14:04
source share

Well, javascript has a try-catch. Depending on what you really need to do (for example, your else will look if it is undefined ), this may be what you want.

Example:

 try { user.loc.lat.doSomething(); } catch(error) { //report } 
+18
May 22 '14 at 13:58
source share

You can combine checks with lazy and :

 if(user.loc && user.loc.lat) { ... 

Or you use CoffeeScript and write

 user.loc?.lat ... 

which will run checks for the loc property and protect against empty objects.

+6
May 22 '14 at 2:00
source share

Try if(user && user.loc && user.loc.lat) {...}

You can check null and undefined with typeof

If .loc is false than you can try

if(user && user.loc && typeof(user.loc)!=="undefined"){...}

If you have a huge nested object than on

Source

 function checkNested(obj /*, level1, level2, ... levelN*/) { var args = Array.prototype.slice.call(arguments), obj = args.shift(); for (var i = 0; i < args.length; i++) { if (!obj.hasOwnProperty(args[i])) { return false; } obj = obj[args[i]]; } return true; } var test = {level1:{level2:{level3:'level3'}} }; checkNested(test, 'level1', 'level2', 'level3'); // true checkNested(test, 'level1', 'level2', 'foo'); // false 

Update: Try lodash.get

+5
May 22 '14 at 14:01
source share



All Articles