Monday, August 22, 2011

Error when trying to use JSON and jquery libraries together

For the fix for this just use json2.js instead of json.js:
https://github.com/douglascrockford/JSON-js
The problem was that he was replacing the json function in the object.prototype and this breaks jQuery since this is not a very good idea. The new json2.js is much better. Below is the troubles I was having and how I solved it with the json.js but later I ran into other things that was broken in jQuery because of json.js. So just use json2.js instead.
I got this error when I had both json.js and jquery scripts in the same html file:
JSON.parse: unexpected character So I tried updating to the newest jquery 1.6.2 and I got this error: c.replace is not a function
I spent a couple hours trying to track it down.
I noticed that when I leave out the json.js file there are no errors when running any jquery code.
First I looked in json.js and found the lines that made it fail.
In json.js it has this code at the end to actually make the parseJSON function if it doesn't exist:

if(!Object.prototype.toJSONString){
Object.prototype.toJSONString=function(filter){return JSON.stringify(this,filter);};
Object.prototype.parseJSON=function(filter){return JSON.parse(this,filter);};
}}());


Now I tracked this down to the exact part of the jquery code that was causeing the problem.
There is a function called by(a,c) in the jquery file. The variable c had these values:
paddingLeft
paddingRight
opacity
function (filter) { "use strict"; return JSON.stringify(this, filter); }
When it got to the function here it fails since thats not a string but a function that was created using JSON's Object.prototype.toJSONString=function(filter)
I don't know why the function is in this list of css types. To fix it I replaced:
c=c.replace(bp,"-$1").toLowerCase();
with:
c=c.toString().replace(bp,"-$1").toLowerCase();
the toString changes the function to a string.
Then when I run the code it gets to the json function and tries to pass an object to json so I fixed it like this:
Object.prototype.parseJSON=function(filter){if((typeof filter) == 'object') return;return JSON.parse(this,filter);};
This checks if its an object instead of the expected string and returns nothing if thats the case.
I don't want to spend more time trying to figure out the root problem but this hack will make it work for now.

No comments: