How to Safely Parse JSON in Javascript


JSON stands for Javascript Object Notation and has become wildly popular to transport and store data between application, databases and more.

However, it is not always obvious that a piece of data your application is trying to use may be of type JSON, or be correctly sanitised.

Let’s take a simple Javascript function as follows:

function getNameFromJSONString(jsonString) {
    
    // Dangerous!
    json = JSON.parse(jsonString);
    
    // Dangerous again!
    return json.name;
}

What the above function does is take in a string which it believes is a stringified/serialised JSON (perhaps stored in a database), parse it back to a Javascript Object and then return an attribute called name.

Now let’s use the following value for jsonString:

"{"name":"Andrew","colour":"red"}"

If we ran this test, we would get back "Andrew" in our return.

The problem with this sort of thing is that you should always write software for when things could break. But how do we know what could break? An easy way to find out, is to mess with the jsonString test value.

What happens if we call the function with some other data type. A blank value, or something else perhaps?

getNameFromJSONString()

Calling the function without passing in any value will give us the following error:

Uncaught SyntaxError: Unexpected token u in JSON at position 0
    at JSON.parse (<anonymous>)
    at getNameFromJSONString (<anonymous>:3:17)
    at <anonymous>:1:1

The same would be true if we received some arbitrary string, such as getNameFromJSONString("cheesecake").

Luckily, this is quite easy to fix, so let’s adjust our Javascript function to cater for this.

We could just wrap the entire contents of the function in a try catch block:

function getNameFromJSONString(jsonString) {
    try {
        json = JSON.parse(jsonString);
        return json.name;
    } catch (e) {
        console.log("error");
        return false;
    }
}

Or we could do something a bit cleaner:

function getNameFromJSONString(jsonString) {
    
    var valid = false;
    try {
        json = JSON.parse(jsonString);
        valid = true;
    } catch (e) {}
    
    return (valid && json.name) ? json.name : "";
    
}

The second option checks to make sure the JSON was parsed and that there is a key with the value name before attempting to return it. As an added step, a blank string is returned if all else fails. This makes sure that our application always gets a valid value back.