Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In javascript, test for property deeply nested in object graph?

I've got a collection of disparate, complex JSON objects from a CouchDB database. Each contains many levels of nested properties--for example,

tps_report.personnel_info.productivity.units_sold = 8  

I want to iterate through these objects and do stuff with them: for instance,

// writes units sold from each TPS report:
for (i in tpsReports) {
  if (tpsReports[i].personnel_info.productivity.units_sold < 10) {
    fireEmployee();
  }
}

The problem is that many TPS reports don't have all these properties set. So if I try this, I'll get an error the first time the loop gets to a report without the "personnel_info" property and thus tries to find the "productivity" property of "undefined." What I'd rather happen is that the conditional just skips it and continues.

I see two ways around this, both of which seem ugly to me

  1. test for each property separately with nested conditionals
  2. enclose the line in a try/catch block to catch the error and ignore it

What I'd prefer would be something like PHP's isset() function, which won't throw an error regardless of what you feed it--it'll just tell you whether the particular variable you're looking for exists or not. So, like

// writes units sold from each TPS report:
for (i in tpsReports) {
  if (isset(tpsReports[i].personnel_info.productivity.units_sold)){
    if (tpsReports[i].personnel_info.productivity.units_sold < 10) {
      fireEmployee();
    }
  }
}

Any thoughts?

like image 227
thisismyname Avatar asked Dec 29 '22 04:12

thisismyname


1 Answers

function isset(obj, propStr) {
    var parts = propStr.split(".");
    var cur = obj;
    for (var i=0; i<parts.length; i++) {
        if (!cur[parts[i]])
            return false;
        cur = cur[parts[i]];
    }
    return true;
}

Note that the second parameter is a string, so the exception doesn't get thrown when accessing a property on a nonexistent property.

like image 56
Zach Avatar answered Dec 31 '22 15:12

Zach