0

In many places in my code, I have checks similar to the one below. It's very verbose, and ugly. Is there is better way? FYI, I'm using Lodash in all my projects, so I have access to that powerful library.

if (myAssessments[orderId].report &&
    myAssessments[orderId].report[categoryProductCode] &&
    myAssessments[orderId].report[categoryProductCode].categories &&
    myAssessments[orderId].report[categoryProductCode].categories[comment.categoryId]) {

    // Do something related to
    // myAssessments[orderId].report[categoryProductCode].categories[comment.categoryId]
}
Blackbird
  • 2,368
  • 4
  • 26
  • 41
  • you can use recursion for this. To check if null or undefined exist. – Akhil Nov 18 '16 at 10:10
  • 4
    Here http://stackoverflow.com/questions/2631001/javascript-test-for-existence-of-nested-object-key you could find a nice approach. – Christos Nov 18 '16 at 10:11
  • @Christos my question is a duplicate of the one you linked. Can someone mark my question as a duplicate? – Blackbird Nov 18 '16 at 10:31
  • 1
    @Blackbird I don't have this privilege but I just voted for close specifying this link. – Christos Nov 18 '16 at 10:41

5 Answers5

2

Since you use lodash, you might use the has method:

_.has(obj,[orderId, 'report', categoryProductCode, 'categories', comment.categoryId])

https://lodash.com/docs/4.16.6#has

Or the get method to get the value of the object path: https://lodash.com/docs/4.16.6#get

DevDig
  • 1,018
  • 13
  • 19
0

Not elegant way but you can wrap in try catch

var result;
    try{
    result = myAssessments[orderId].report[categoryProductCode].categories[comment.categoryId]
    }catch{}

if (result){
  // do it
}
asdf_enel_hak
  • 7,474
  • 5
  • 42
  • 84
0

Use the built-in isset function:

if (isset(myAssessments[orderId].report) &&
    isset(myAssessments[orderId].report[categoryProductCode]) &&
    isset(myAssessments[orderId].report[categoryProductCode].categories) &&
    isset(myAssessments[orderId].report[categoryProductCode].categories[comment.categoryId)]) {
jurruh
  • 119
  • 6
0

You could use an array with all properties to check and iterate until all properties have been checked.

function checkProperties(object, keys) {
    return keys.every(function (key) {
        if (key in object) {
            object = object[key];
            return true;
        }
    });
}

// usage
if (checkProperties(myAssessments, [orderId, 'report', categoryProductCode, 'categories', comment.categoryId])) {
    // Do something related to
    // myAssessments[orderId].report[categoryProductCode].categories[comment.categoryId]
}
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

I have this genric function

function chckForKeyPresence(data, arr, checkLength){
    var currData = data;
    for(var i=0; i<arr.length; i++){
        if(!currData.hasOwnProperty(arr[i]))
            return false;

        currData = currData[arr[i]];
    }

    if(checkLength)
        if(currData.length==0)
            return false;

    return true;
}

Here 1st argument is the main data, 2nd argument is the array of properties you need to check and the third argument will check the length of the last element that it is 0 or not, it will check only if the third argument is true.

You can use it like:

if(!chckForKeyPresence(data, ["results", "tweets"], true)){
    // error
    return;
}
void
  • 36,090
  • 8
  • 62
  • 107