Reputation: 565
I have a object for example:
var extra = {
field1: {
foo: {},
bar: {}
}
}
field1
is not guaranteed to be set, If I need to check the existence of extra.field1.foo
, I have to use:
if(typeof extra.field1 != 'undefined') {
if(typeof extra.field1.foo != 'undefined') {
....
}
}
Is there any simpler way to do the check?
Upvotes: 2
Views: 94
Reputation: 4819
You could create a function that takes an array (or a string) and checks for each element in it, then you can check the existence of every nested property with only one conditional in your code.
obj1 = {
field1: {
col1: 1,
col2: 'a'
}
};
function checkExistence(arr) {
// if arr is a string convert it into an array before checking it
if (typeof arr == 'string') {
arr=arr.split('.');
}
checked = arr[0]; i = 1;
checks = window.hasOwnProperty(checked);
while (checks && i < arr.length) {
checked+='.'+arr[i];
checks = typeof eval(checked) != 'undefined';
++i;
}
if (!checks) console.log(checked+' is undefined');
else console.log(checked+' is defined');
return checks;
}
checkExistence(['obj1','field1','col1']);
// obj1.field1.col1 is defined
checkExistence(['obj1','field1','col3']);
// obj1.field1.col3 is undefined
checkExistence(['obj1','field2','col3']);
// obj1.field2 is undefined
checkExistence(['obj2','field2','col3']);
// obj2 is undefined
checkExistence('obj1.field1.col1');
// obj1.field1.col1 is defined
...
if (checkExistence('obj1.field2.value1')) {
// do something
}
Upvotes: 1
Reputation: 3536
This method can check any depth with no limit.
function exists(node, chainString) {
return chainString.split('.')
.every(prop => node && prop in node ? (node = node[prop]) || true : false);
}
nodes = [
{x: { y: { z: 43 }}},
{x: { y: { z: undefined }}},
{x: { y: null }},
{x: []},
];
console.log(nodes.map(n => exists(n, "x.y.z")));
Upvotes: 0
Reputation: 3003
If you just want to know if an object has a particular property, no matter where in the prototype chain, you could use the in
operator:
if (myprop in myobj) {
...
}
Consider that his method will check all the properties and method that your object has and the method it get from the 'language'. As an example:
var o = {
"myprop": true
};
if ("toString" in o) {
console.log('toString exists');
}
It prints out 'toString exists'.
If you're interested in checking just inside the object, you have to use:
if (Object.hasOwnProperty.call(myobject, myprop)) {
...
}
This avoids the inherited method like toString
and hasOwnProperty
.
The dirty way is using the !!
method:
if (!!myobject[myprop]) {
....
}
This way force to convert any myobject[myprop]
to a boolean value.
The issue with this, is when you could have values that could convert in false, like empty string or null or undefined or, of course, a boolean false!
Upvotes: 0
Reputation: 1
Use Object's hasOwnProperty(prop) for this task.
if (extra.hasOwnProperty('field1') && extra.field1.hasOwnProperty('foo')) {
// ...
}
Upvotes: 0
Reputation: 19060
You can use Object.prototype.hasOwnProperty() as well as in operator. But for simplicity you can check the existence of properties like this:
if (extra.field1 && extra.field1.foo ) {
// ...
}
Upvotes: 3
Reputation: 386522
You could use the in
operator.
The
in
operator returnstrue
if the specified property is in the specified object.
if ('field1' in extra && 'foo' in extra.field1) {
// true for foo
}
Upvotes: 4
Reputation: 10342
You always will have to check both fields, but you can write it in different ways. If you are sure that you are checking objects, then the following code would be safe enough:
if (extra.field1) { //if field1 is not null / undefined / zero / empty string / false
if (extra.field.foo) {...}
...
}
That won't be safe if field1 can be 0 or an empty string, because both are "falsy" values
Upvotes: 0