Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stringify (convert to JSON) a JavaScript object with circular reference

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?

like image 348
user1012500 Avatar asked May 01 '12 00:05

user1012500


People also ask

How do you resolve converting circular structure to JSON?

The "Converting circular structure to JSON" error occurs when we pass an object that contains circular references to the JSON. stringify() method. To solve the error, make sure to remove any circular references before converting the object to JSON. Here are some examples of how the error occurs.

Can you JSON Stringify an object?

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.

How do you convert circular structure to string?

A circular structure is an object that references itself. To be able to stringify such objects, developers can utilize the replacer parameter in the stringify() method, making sure the function that is being passed in, filters out repeated or circular data.


1 Answers

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:

JSON.stringify( that.person, function( key, value) {   if( key == 'parent') { return value.id;}   else {return value;} }) 

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:

function Person( params) {   this.id = params['id'];   this.name = params['name'];    this.father = null;   this.fingers = [];   // etc. }  var me = new Person({ id: 1, name: 'Luke'}); var him = new Person( { id:2, name: 'Darth Vader'}); me.father = him;  JSON.stringify(me); // so far so good  him.father = me; // time travel assumed :-) JSON.stringify(me); // "TypeError: Converting circular structure to JSON" // But this should do the job: JSON.stringify(me, function( key, value) {   if(key == 'father') {      return value.id;   } else {     return value;   }; }); 

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...

like image 85
tocker Avatar answered Oct 10 '22 07:10

tocker