Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In JavaScript, is there an easier way to check if a property of a property exists?

Is there an easy way to natively determine if a deep property exists within an object in JavaScript? For example, I need to access a property like this:

var myVal = appData.foo.bar.setting;

But there is a chance that either foo, foo.bar, or foo.bar.setting has not been defined yet. In Groovy, we can do something like this:

def myVal = appData?.foo?.bar?.setting

Is there a similar way to do this in JavaScript, without having to write a custom function or nested if statements? I've found this answer to be useful, but was hoping there was a more elegant and less custom way.

like image 605
A.J. Brown Avatar asked Oct 03 '11 15:10

A.J. Brown


People also ask

How do you check if a property exists in an array of objects JavaScript?

To check if a JavaScript array contains an object:findIndex method on the array. Check if each object in the array contains a property with the specific value. The Array. findIndex method will return the index of the object in the array, or -1 if the object is not in the array.

How do you check if a value is present in an object in JavaScript?

You can use Object. values(): and then use the indexOf() method: The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.

How do you check if a property exists in an object TypeScript?

To check if a property exists in an object in TypeScript: Mark the specific property as optional in the object's type. Use a type guard to check if the property exists in the object. If accessing the property in the object does not return a value of undefined , it exists in the object.


3 Answers

I find this very convenient:

var myVal = (myVal=appData) && (myVal=myVal.foo) && (myVal=myVal.bar) && myVal.settings;

If a property exists, the next part of the sequence will be attempted.

When the expression before && evaluates to false, the next part of the expression will not be checked. If either of myVal.appData.foo.bar.settings is not defined, the value of myVal (undefined( will evaluate to false.

like image 174
Rob W Avatar answered Oct 16 '22 11:10

Rob W


Sorry, it's not great:

var myVal = appData && appData.foo && appData.foo.bar && appData.foo.bar.setting;

Another option:

try {
    var myVal = appData.foo.bar.setting;
} catch (e) {
    var myVal = undefined;
}

The . operator is not really intended for accessing objects like this. Probably using a function would be a good idea.

like image 23
robert Avatar answered Oct 16 '22 11:10

robert


I find other approaches a bit immense. So, what would be the major drawback of the following approach:

// Pass the path as a string, parse it, and try to traverse the chain.
Object.prototype.pathExists = function(path) {
    var members = path.split(".");
    var currentMember = this;

    for (var i = 0; i < members.length; i++) {
        // Here we need to take special care of possible method 
        // calls and arrays, but I am too lazy to write it down.
        if (currentMember.hasOwnProperty(members[i])) {
            currentMember = currentMember[members[i]];   
        } else {
            return false;
        }
    }
    return true;
}

Basically, we define a method on the object (not necessarily) and that method takes the path to a nested object and returns existence confirmation, likeappData.pathExists("foo.bar.setting");

EDIT: Check object[prop] == undefined is not semantically correct since it will return false even if the property is defined although its value is undefined; that is why I use hasOwnProperty to check is the property defined. This might not be important if one needs to just fetch the value.

like image 36
bellpeace Avatar answered Oct 16 '22 11:10

bellpeace