I've got a JavaScript object definition which contains a circular reference: it has a property that references the parent object.
It also has functions that I don't want to be passed through to the server. How would I serialize and deserialize these objects?
I've read that the best method to do this is to use Douglas Crockford's stringify. However, I'm getting the following error in Chrome:
TypeError: Converting circular structure to JSON
The code:
function finger(xid, xparent){
this.id = xid;
this.xparent;
//other attributes
}
function arm(xid, xparent){
this.id = xid;
this.parent = xparent;
this.fingers = [];
//other attributes
this.moveArm = function() {
//moveArm function details - not included in this testcase
alert("moveArm Executed");
}
}
function person(xid, xparent, xname){
this.id = xid;
this.parent = xparent;
this.name = xname
this.arms = []
this.createArms = function () {
this.arms[this.arms.length] = new arm(this.id, this);
}
}
function group(xid, xparent){
this.id = xid;
this.parent = xparent;
this.people = [];
that = this;
this.createPerson = function () {
this.people[this.people.length] = new person(this.people.length, this, "someName");
//other commands
}
this.saveGroup = function () {
alert(JSON.stringify(that.people));
}
}
This is a test case that I created for this question. There are errors within this code but essentially I have objects within objects, and a reference passed to each object to show what the parent object is when the object is created. Each object also contains functions, which I don't want stringified. I just want the properties such as the Person.Name
.
How do I serialize before sending to the server and deserialize it assuming that the same JSON is passed back?
It appears that dojo can represent circular references in JSON in the form :
{"id":"1","me":{"$ref":"1"}}
Here is an example:
http://jsfiddle.net/dumeG/
Produces:
Note: You can also de-serialize these circular referenced objects using the
dojox.json.ref.fromJson
method.Other Resources:
How to serialize DOM node to JSON even if there are circular references?
JSON.stringify can't represent circular references
I used the following to eliminate the circular references:
I found two suitable modules to handle circular references in JSON.
Either of these should meet your needs.
Happened upon this thread because I needed to log complex objects to a page, since remote debugging wasn't possible in my particular situation. Found Douglas Crockford's (inceptor of JSON) own cycle.js, which annotates circular references as strings such that they can be reconnected after parsing. The de-cycled deep copy is safe to pass through JSON.stringify. Enjoy!
https://github.com/douglascrockford/JSON-js
Circular structure error occurs when you have a property of the object which is the object itself directly (
a -> a
) or indirectly (a -> b -> a
).To avoid the error message, tell JSON.stringify what to do when it encounters a circular reference. For example, if you have a person pointing to another person ("parent"), which may (or may not) point to the original person, do the following:
The second parameter to
stringify
is a filter function. Here it simply converts the referred object to its ID, but you are free to do whatever you like to break the circular reference.You can test the above code with the following:
BTW, I'd choose a different attribute name to "
parent
" since it is a reserved word in many languages (and in DOM). This tends to cause confusion down the road...