Tuesday, June 2, 2009

JSON – Traps and How to Avoid Them



Disclaimer: This post is suggestive but not complete




When you are working with JSON there are plenty of chances that things may go wrong. We all know that when something can go wrong it will go wrong. JSON never mentions the data type or it does not get validated by existing JS engines that run on the browser – so the onus lies on the developer to make sure that the data that she has received is in correct format and if possible the value is correct.



Any one can think about whole bunch of defensive programming techniques to avoid such a scenario. But it is impossible to guess what all things can go wrong so we should be prepared as much as possible.



Never evaluate a JSON. It is as bad as it can be. Don’t do it. You do not what you have received in the JSON. If it is a malicious code it can do havoc on your DOM and JS environment. It can corrupt your JS name space, steal cookie information or even worse user information. I know you must be thinking that we have to do it time and again, use json2.js library for this purpose – please do not repeat yourself with all the JSON string parsing again.



JSON data access is where your code will break (I mean eventually). Say you have a JSON structure (produced by the server) like this one:




{ name : { first : “Joe”, middle : ”Moe” , last : “Doe” }, age : 23 }




Now you wrote the logic like this:




var name = json.name.first + “ “+ json.name.middle +” “+ json.name.last;




This look pretty straight forward and you are sure nothing can go wrong with this simple code. But your server works with this logic: If there is a middle name then it adds middle name if it is not there it keeps mum about that. So the JSON comes like this:




{ name : { first : “Joe” , last : “Doe” }, age : 23 }




Your code now will not work as expected, the reason being the absence of name.middle object. This is undefined.



So how do you make sure that it works as expected? Here is how:




var name = “unknown”;
If (json.name.first & json.name.middle & json.name.last) {
name = json.name.first + “ “+ json.name.middle +” “+ json.name.last;
}




This is more important when it comes to calling some methods on a JavaScript object. If the object does not exist (i.e., undefined) then it will throw an error and your rest of the script won’t run. So if you are working with some JSON and you expect some kind of an object check the type of the object before invoking the method on it. Like if you want to split some CSV (comma separated value) string check that the object is of string type.




if (csvObject instanceof String) {
// Do your stuff here for string
}