1. use try/catch
In your statement you have:
- 26 potential sources for Reference errors (16 missing objects, 10 array out of bounds).
That's what try/catch handles best. Dealing with the same type of error from a block of code and handling in one place. So unless you want to deal with each potential error individually, try/catch is the simplest and best tool you at your disposal. It works and you can pinpoint the problem:
var w = {}
try {w.x.y.z} catch(e) {e}
TypeError: Cannot read property 'y' of undefined(…)
Alternatively, if you need more control, you could
2. test all references up-front
If it must succeed even if some properties fail, you can check each reference. e.g.:
var sdValid = data &&
data.actions &&
data.actions.length>1 &&
data.actions[0].causes &&
data.actions[0].causes.length &&
data.actions[1].causes[0].shortDescription;
var owner = sdValid
? data.actions[1].causes[0].shortDescription
: 'default value';
this.response = {
owner : owner,
// etc...
}
You can easily make it more readable if you
3. roll out your own reference checker
this.response = {
owner : nestget(data, 'nobody')
.prop('actions', 1)
.prop('causes', 0)
.prop('shortDescription')
.value(),
// return shortDescription if you got this far or 'nobody'
build_version : nestget(data, '0.0.0')
.prop('actions', 0)
.prop('parameters', 0)
.prop('value')
.value(),
// return value if you got this far or '0.0.0'
// ... etc
};
// Custom - easy to use reference checker
function nestget (obj, default) {
var valid = false;
this.default = default;
this.obj = obj;
var that = this;
return {
prop : propChecker,
value : getValue
}
function propChecker (prop, i) {
// implementation omitted for brevity
}
function getValue () {
return value;
}
}
4. use a library
Last but not least, you can always use a library. Personally I like how XPath searches XML trees so I would suggest using something like JSONPath to search for nested objects in a data structure. e.g.
this.response = {
owner : jsonpath(data, '$..shortDescription[0]'),
build_version jsonpath(data, '$.actions[0].parameters[0].value'), // no error
// ... etc
}
However, there are lots of options out there (e.g. lodash/underscore as mentioned in a comment).