Sebastien Daniel
Sebastien Daniel

Reputation: 4778

API data and variable undefined

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 ifs:

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

Answers (2)

Calvin Froedge
Calvin Froedge

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

Barmar
Barmar

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

Related Questions