Opened 14 years ago

Closed 14 years ago

Last modified 12 years ago

#222 closed enhancement (fixed)

JSON stringifying code

Reported by: martinc Owned by: anonymous
Priority: high Milestone:
Component: General Version: 0.1
Keywords: JSON Cc:
Blocked By: Blocking:

Description

The attached file, json.js, contains an implementation of JSON stringifying code, as a dojo.json package. Functions taking specific types are provided, but the "main" function is 'itemToString', which will figure out what you give it and call the appropriate function to do the work.

Note that, since JSON doesn't support nodes or functions, this implementation will substitute "(NODE)" or "(FUNCTION)" if it encounters such a thing. I wasn't sure what else to do in those cases. Perhaps it should throw instead.

Attachments (1)

json.js (1.3 KB) - added by martinc 14 years ago.

Download all attachments as: .zip

Change History (12)

Changed 14 years ago by martinc

Attachment: json.js added

comment:1 Changed 14 years ago by martinc

Forgot to mention - this file differs slightly from the one originally sent to Alex insofar as it brings it into compliance with Dojo coding standards.

comment:2 Changed 14 years ago by eugene@…

It looks nice (modulo code standards). I have some suggestions:

  1. JSON doesn't understand NaN. If isNan(number), it should be substituted by null.
  2. Most probably undefined should be encoded as null as well instead of a string.
  3. I would sleep better, if the switch statement had default: clause. ;-) Let's treat it as undefined object.
  4. arrayToString/objectToString use += to build the representation. It may hog a lot of CPU for long arrays/objects doing unnecessary reallocations with copying. Personally I would build array of strings out of individual components, which can be glued together at the end using Array.join("") (or any other suitable separator). There is dojo.string.Builder, which can help to do it.

Code standard enforcement is up to Alex & Co.

comment:3 Changed 14 years ago by david

Reply to Eugene's comments:

  1. Why is NaN unsupported? We should be able to handle that just fine.
  2. undefined and null aren't the same thing. null is a type of an object, where undefined is a constant of sorts.
  3. If we don't know how to serialize something, it should be ignored, at least IMO. Not sure what the spec says.
  4. Yes, the code should probably leverage Array.join, the variable first being the dead giveaway.

A couple other comments:

  1. dojo.lang.whatAmI should probably be leveraged for the switch. That wasy you don't have to make array a sub-case of object.
  2. It'd be nice if this thing was extendable, so you'd have something like:
dojo.json.rules = [
 function(wh) {
  // decide if node passes a filter
 },
 function(wh) {
  // convert 'wh' to a string somehow
 }
];

That, of course, if a very naive implementation, but I think making it pluggable would be beneficial.

comment:4 Changed 14 years ago by eugene@…

Reply to David:

  1. Yep. My point was to alert that passing NaN as a value is unsupported by JSON. Because this code is meant for server callbacks, we cannot rely on any deviation from JSON specification.
  2. I agree. The point is: undefined is not supported by JSON. I don't think that passing string "undefined" is a proper relacement but this is my personal opinion --- obviously there are different strategies.
  3. It is a valid strategy. But we should deal with it properly. Example: [1, something, 2] should not be serialized as [1,,2], because it isn't valid JSON. But this output is produced by attached code.
  4. Thanks.

A sidenote: the code doesn't deal with null at all but null is part of JSON specification. I think null handling should be added.

comment:5 Changed 14 years ago by cris@…

Note that recent versions of Dojo already include a JSON stringifier for widget state maintenance. The existing code can be called with an option to display "all" properties of its object, but for persistence or communication purposes, this should not be turned on, because the values will not in general be possible to process with "eval". Path:

src/widget/html/stabile.js

I contributed this, and Bill Keese entered it in SVN. The function is named "describe", and I don't care where it goes in the source tree.

For widget state maintenance the requirements are very similar to the requirements for server communication.

-Cris

comment:6 Changed 14 years ago by eugene@…

Obviously we should prevent duplication. Nevertheless the existing code in stabile.js suffers from the same problems, which boiled down to: it is not JSON compliant. Please see the discussion above.

comment:7 Changed 14 years ago by cris@…

In response to Eugene's comments --

If JSON-compliant output is key for you, the code in stabile.js would at least need some modifications, because it does not quote string keys that are legal identifiers. Offering a true JSON string creator sounds like a fine idea to me, for JavaScript?-to-server communication, for example.

For my purpose, JSON compliance was not the top priority, but ability to eval the output was key, and being able to save and restore a relatively rich set of data structures was a goal, one I think likely to be shared by other persistence-oriented, JavaScript?-specific uses.

A subset of JavaScript? data structures map cleanly to pure JSON. A larger subset can map to JavaScript? literals that can be eval'ed with useful results. A common codebase could support both purposes if desired. Some users might want a version with strict input checking for example, and a guarantee of meaningful pure JSON output.

comment:8 Changed 14 years ago by alex

Milestone: 0.2release

comment:9 Changed 14 years ago by martinc

Any reason I shouldn't just close this ticket now? The desired result - JSON stringify code in Dojo - has been achieved, even if it isn't the code I originally posted. ;-)

comment:10 Changed 14 years ago by alex

Resolution: fixed
Status: newclosed

I'm gonna close this. Any further discussion of JSON object serializer bugs should be taken up in a new ticket. Thanks everyone.

comment:11 Changed 12 years ago by (none)

Milestone: 0.2release

Milestone 0.2release deleted

Note: See TracTickets for help on using tickets.