Reputation: 1883
Is there a simpler way than using ___ in object
to check the existence of each level of an object to check the existence of a single member?
More concisely: How can I check if someObject.member.member.member.value exists?
Upvotes: 27
Views: 15417
Reputation: 8109
If you can use lodash
library, it has a very elegant solution, hasIn.
_.hasIn(someObject, 'member.level1.level2.level3');
for example,
var obj = {'x': 999, 'a': {'b': {'c': 123, 'd': 234}}}
// => undefined
_.hasIn(obj, 'x')
// => true
_.hasIn(obj, 'a.b.d')
// => true
_.hasIn(obj, 'a.b.e')
// => false
Upvotes: 0
Reputation: 1475
Check out lodash-deep’s deepHas
https://github.com/marklagendijk/lodash-deep#_deephascollection-propertypath
And this too https://github.com/danielstjules/hoops
Upvotes: 3
Reputation: 1213
Theres a safeRead function defined here on thecodeabode which allows a safeRead of nested properties i.e.
safeRead(foo, 'bar', 'jim', 'jam');
if any of the properties are null or undefined a blank string is returned - useful for formatting / string interpolation
Upvotes: 2
Reputation: 117
You could also try/catch TypeError?
try {
console.log(someObject.member.member.member.value);
} catch(e) {
if (e instanceof TypeError) {
console.log("Couldn't access someObject.member.member.member.value");
console.log(someObject);
}
}
Upvotes: 7
Reputation: 816462
In general, you can use if(property in object)
, but this would be still cumbersome for nested members.
You could write a function:
function test(obj, prop) {
var parts = prop.split('.');
for(var i = 0, l = parts.length; i < l; i++) {
var part = parts[i];
if(obj !== null && typeof obj === "object" && part in obj) {
obj = obj[part];
}
else {
return false;
}
}
return true;
}
test(someObject, 'member.member.member.value');
Upvotes: 36
Reputation: 44386
Something like (warning: untested code ahead)
var testProperty = function(obj, proplist) {
for (var i=0; i < proplist.length; i++) {
if (obj.hasOwnProperty(proplist[i])) {
obj = obj[proplist[i]];
} else {
return false;
}
}
return true;
}
Upvotes: 2
Reputation: 322502
Here's one way: http://jsfiddle.net/9McHq/
var result = ((((someObject || {}).member || {}).member || {}).member || {}).value;
alert( result );
Upvotes: 4
Reputation: 303253
if (someObject.member && someObject.member.member &&
someObject.member.member.member && someObject.member.member.member.value) ...
or similarly:
var val = foo.bar && foo.bar.jim && foo.bar.jim.jam && foo.bar.jim.jam.value;
This will not 'work' if any particular value happens to be null
, false
, 0
, or ""
(an empty string), but with the possible exception of the final value, this seems unlikely to be the case.
Also, note that typeof ____ !== "undefined"
is not the correct test to see if an object has a property. Instead you should use ___ in object
, e.g. if ("member" in someObject)
. This is because you can set a property to an explicit value of undefined
, which is different from removing it with delete someObject.member
.
Upvotes: 2