1

I have json like this

var a = {
    "name": "test1",
    "redisData": {
        "redisIp": "127.0.0.1",
        "dbSetting": {
            "dbIp": "127.0.0.1",
            "dbUserName": "root",
            "dbUserPassword": "root",
        },
        "otherData":{
            "email":"a@gmail.com"
        }
    }
}

So i have to push this data in database when all the data present in all key for that purpose i have to validate that data like this

if (a.hasOwnProperty("redisData")) {
    if (a.redisData.hasOwnProperty("dbSetting")) {
        if (a.redisData.dbSetting.hasOwnProperty("dbIp")) {
            if (a.redisData.dbSetting.dbIp) {
                // now insert in to database
            } else {
                alert('DB server Ip missing');
            }
        } else {
            alert('DB server Ip missing');
        }
    } else {
        alert('DB server Ip missing');
    }
} else {
    alert('DB server Ip missing');
}

But this code looks ugly. Do we have better way to avoid multiple if condition and chaining of hasownproperty.

Dexter
  • 1,804
  • 4
  • 24
  • 53
  • `a.hasOwnProperty("redisData") && a.redisData.hasOwnProperty("dbSetting") && …`? – Bergi Aug 14 '18 at 12:23
  • If you didnt need those alerts, i would have suggested a `try catch` .. but if you need those alerts, you always want to check for each property dont you.. – callback Aug 14 '18 at 12:24
  • You can also use `"redisData" in a && …` for simplicity or even just `a.redisData && …` given its value is a truthy object – Bergi Aug 14 '18 at 12:24
  • @callback It's the same alert. He can use `if (… && … && … && …) { … } else { alert('DB server Ip missing'); }` – Bergi Aug 14 '18 at 12:25

6 Answers6

3

Simple: Just check if the values exist and have a truthy value:

if (a.redisData && a.redisData.dbSetting && a.redisData.dbSetting.dbIp) {
    // now insert in to database
} else {
    alert('DB server Ip missing');
}

There is no real advantage in using hasOwnProperty here.

Cerbrus
  • 70,800
  • 18
  • 132
  • 147
2

You can use a try catch clause like:

try {
   if (a.redisData.dbSetting.dbIp) {
     // now insert in to database
   } else {
       alert('DB server Ip missing');
   }
} catch(e) {
   alert('DB server Ip missing');
}
callback
  • 3,981
  • 1
  • 31
  • 55
1

Here's the simple function from library ramda.js that will help you to get any nested property in a safe way:

function path(paths, obj) {
    var val = obj;
    var idx = 0;
    while (idx < paths.length) {
      if (val == null) {
        return;
      }
      val = val[paths[idx]];
      idx += 1;
    }
    return val;
};

const dbIp = path(["redisData","dbSetting","dbIp"], a)
if(dbIp) {
    // now insert in to database
}
ykit9
  • 483
  • 4
  • 7
1

You could write a function like this if you really need to check hasOwnProperty at each stage and want to know at which stage the key is not found.

function hasNestedProperty(obj, keys) {
    for(let key of keys) {
        if (obj.hasOwnProperty(key)) {
            obj = obj[key];
        }
        else {
            return {result: null, found: false, lastKey: key}
        }
    }
    return {result: obj, found: true}
}
...
var r = hasNestedProperty(a, ["redisData", "dbSetting", "dbIp"]);
if (r.found) {
    // insert into DB using r.result
}

But in most cases either try...catch or an if with &&s will probably do what you need.

Stuart
  • 9,597
  • 1
  • 21
  • 30
1

You can use https://lodash.com/docs/4.17.10#has

    var databaseIP = _.has(a, 'redisData.dbSetting.dbIp');

    if (databaseIP) {
       // now insert in to database
    }
    else {
     alert('DB server Ip missing');
    }
Akash Gadhiya
  • 380
  • 1
  • 15
0

You can use lodash _.get() method for that problem

var ip = _.get(a.redisData, 'dbSetting.dbIp');

if (ip) {
   //insert into database
} else {
   // not found IP
}
Rock
  • 57
  • 12