Reputation: 4778
I'm parsing some data that I fetched, but some of the data in the JSON
is not defined.
For example, a contact object can have first_name
, last_name
, and job_title
, but sometimes job_title
is not set.
To avoid my scripts crashing because of this undefined variable, I check to make sure the variable exists:
if (this.data[x]) {
// do your thing
}
I have to put these checks all over the place and, on particularly large scripts, it makes my code difficult to follow.
Is there a better way to tell my code to keep running even if it hits an undefined variable? For example, if an undefined value is met anywhere in the path, return an empty string.
Below is an example of a situation where this would be helpful because I could cut back on all the if
s:
var filtrate;
if (d.ContactValues) {
filtrate = d.ContactValues.filter(function(o) {
return o.RefContactMethod.key === 'office_phone';
});
if (filtrate.length > 0) {
return filtrate[0].value;
}
//... additional if statements ...
}
EDIT #1
Just to keep you all posted, I ran some basic performance tests: http://jsperf.com/undefined-var-try-catch-and-other
I will run a more in-depth and real-world tests later today.
Upvotes: 1
Views: 448
Reputation: 16373
You're looking for exception handling:
try {
// Do something that can throw an exception
} catch(err) {
console.log('the error was ' + err);
// set a default value, or whatever
}
This is exactly what exceptions are designed for (gracefully handling errors in a program and continuing smoothly). If you want to catch the undefined variable and set it to a default value:
catch(e if e instanceof TypeError){
if ( /'/.test( err.message ) ){
prop = err.message.match( /'(.*?)'/ )[1];
obj['wasundefined'] = {}
obj['wasundefined'][prop] = "my value";
}
}
This works because the error message for TypeError follows the pattern: TypeError: Cannot read property 'c' of undefined
Upvotes: 1
Reputation: 782166
After you parse the JSON, you can fill in the object with default values:
fields = ['first_name', 'last_name', 'job_title'];
for (var i = 0; i < fields.length; i++) {
if (!(fields[i] in object)) {
fields[i] = '';
}
}
Another option would be to write your own getProp
function:
function getProp(obj, property, default) {
if (property in obj) {
return obj[property];
} else {
return default;
}
}
Then use getProp(obj, 'job_title', '')
instead of obj.job_title
.
This could be rewritten with try/catch
, it might be more efficient that way:
function getProp(obj, property, default) {
try {
return obj[property];
} catch (e) {
return default;
}
}
Upvotes: 1