Reputation: 8582
I have a situation similar with the one here: Javascript check if object property exists, even when object is undefined.
My problem is, what happens if you have a chain of properties. Example:
var obj = {'a': {'b': {'c': {'d': 'I exists'}}}}
I need to check if 'd' is defined. In order to not get an error, I would have to check like:
if (typeof obj != 'undefined' && typeof obj['a'] != 'undefined' && typeof obj['a']['b'] != 'undefined' && typeof obj['a']['b']['c'] != 'undefined' && typeof obj['a']['b']['c']['d'] != 'undefined')
You can see how this can get annoying. Extrapolate to a level 999 deep element for example. Is there any way to get rid of the first n-1 conditions?
Upvotes: 4
Views: 396
Reputation: 27
var obj = {a:undefined,b:undefined,c:undefined,d:'I exists'};
if(typeof obj['a'] === 'object'){alert(typeof obj['a']);}
else if(typeof obj['b'] === 'object'){alert(typeof obj['b']);}
else if(typeof obj['c'] === 'object'){alert(typeof obj['c']);}
else{alert(typeof obj['d']+' : '+obj['d']);}
check here http://www.w3schools.com/js/js_datatypes.asp for datatype and here http://www.w3schools.com/js/js_arrays.asp for array.
Upvotes: 0
Reputation: 12184
Try to write your own property checker like next one:
JavaScript:
function test(object) {
var restOfKeys = [];
for (var _i = 1; _i < arguments.length; _i++) {
restOfKeys[_i - 1] = arguments[_i];
}
var propertyToTest;
if (object === undefined || !restOfKeys.length) {
return false;
}
propertyToTest = restOfKeys.shift();
if (restOfKeys.length) {
return test.apply(void 0, [object[propertyToTest]].concat(restOfKeys));
}
return object[propertyToTest] !== undefined;
}
var toTest = { a: { b: { c: "asd" } } };
alert(test(toTest, "a", "b", "c"));
TypeScript:
function test(object: any, ...restOfKeys: string[]) {
let propertyToTest: string;
if (object === undefined || !restOfKeys.length) {
return false;
}
propertyToTest = restOfKeys.shift();
if (restOfKeys.length) {
return test(object[propertyToTest], ...restOfKeys);
}
return object[propertyToTest] !== undefined;
}
var toTest = { a: { b: { c: "asd" } } };
alert(test(toTest, "a", "b", "c"));
Source Code here
Upvotes: 0
Reputation:
Solution with try-catch:
var check = function(obj) {
try {
return (typeof obj.a.b.c.d !== 'undefined');
} catch (e) {
return false;
}
};
alert(check({
'a': {
'b': {
'c': {
'd': 'I exists'
}
}
}
}));
Upvotes: 4
Reputation: 87203
You can check the value for truthy as follow.
You can't get rid of the first n - 1
conditions but you can shorten your statement
if (obj && obj.a && obj.a.b && obj.a.b.c && typeof obj.a.b.c.d !== 'undefined')
// Use of obj.a.b.c.d is considered safe here
Upvotes: 1
Reputation: 3029
Like Tushar said in his answer:
You can't get rid of the first
n - 1
conditions
So you will just have to shorten your statement, so it's not as long.
Check this following example i've created:
var obj = {'a': {'b': {'c': {'d': 'I exists'}}}};
for (var key in obj)
{
if (obj && obj.a.b.c.d)
{
console.log(obj.a.b.c.d);
}
}
Upvotes: 1
Reputation: 172418
You can try like this:
function checkUndefined(obj) {
var x = Array.prototype.slice.call(arguments, 1);
for (var i = 0; i < x.length; i++) {
if (!obj || !obj.hasOwnProperty(x[i])) {
return false;
}
obj = obj[x[i]];
}
return true;
}
Upvotes: 1