Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON.stringify() array bizarreness with Prototype.js

I'm trying to figure out what's gone wrong with my json serializing, have the current version of my app with and old one and am finding some surprising differences in the way JSON.stringify() works (Using the JSON library from json.org).

In the old version of my app:

 JSON.stringify({"a":[1,2]}) 

gives me this;

"{\"a\":[1,2]}" 

in the new version,

 JSON.stringify({"a":[1,2]}) 

gives me this;

"{\"a\":\"[1, 2]\"}" 

any idea what could have changed to make the same library put quotes around the array brackets in the new version?

like image 372
morgancodes Avatar asked Apr 02 '09 16:04

morgancodes


People also ask

Can you JSON Stringify an array?

Stringify a JavaScript ArrayIt is also possible to stringify JavaScript arrays: Imagine we have this array in JavaScript: const arr = ["John", "Peter", "Sally", "Jane"]; Use the JavaScript function JSON.

What happens when you JSON Stringify an array?

The JSON. stringify() method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.

What is the purpose of JSON Stringify () and parse () methods?

The JSON. parse() function is used to convert a string into a JavaScript object while the JSON. stringify() function is used to convert a JavaScript object into a string.

Does JSON Stringify work on nested objects?

stringify does not stringify nested arrays. Bookmark this question. Show activity on this post.


2 Answers

Since JSON.stringify has been shipping with some browsers lately, I would suggest using it instead of Prototype’s toJSON. You would then check for window.JSON && window.JSON.stringify and only include the json.org library otherwise (via document.createElement('script')…). To resolve the incompatibilities, use:

if(window.Prototype) {     delete Object.prototype.toJSON;     delete Array.prototype.toJSON;     delete Hash.prototype.toJSON;     delete String.prototype.toJSON; } 
like image 98
Raphael Schweikert Avatar answered Sep 20 '22 10:09

Raphael Schweikert


The function JSON.stringify() defined in ECMAScript 5 and above (Page 201 - the JSON Object, pseudo-code Page 205), uses the function toJSON() when available on objects.

Because Prototype.js (or another library that you are using) defines an Array.prototype.toJSON() function, arrays are first converted to strings using Array.prototype.toJSON() then string quoted by JSON.stringify(), hence the incorrect extra quotes around the arrays.

The solution is therefore straight-forward and trivial (this is a simplified version of Raphael Schweikert's answer):

delete Array.prototype.toJSON 

This produces of course side effects on libraries that rely on a toJSON() function property for arrays. But I find this a minor inconvenience considering the incompatibility with ECMAScript 5.

It must be noted that the JSON Object defined in ECMAScript 5 is efficiently implemented in modern browsers and therefore the best solution is to conform to the standard and modify existing libraries.

like image 35
Jean Vincent Avatar answered Sep 22 '22 10:09

Jean Vincent