Serializing Object That Contains Cyclic Object Value

Serializing object that contains cyclic object value

Use the second parameter of stringify, the replacer function, to exclude already serialized objects:

var seen = [];

JSON.stringify(obj, function(key, val) {
if (val != null && typeof val == "object") {
if (seen.indexOf(val) >= 0) {
return;
}
seen.push(val);
}
return val;
});

http://jsfiddle.net/mH6cJ/38/

As correctly pointed out in other comments, this code removes every "seen" object, not only "recursive" ones.

For example, for:

a = {x:1};
obj = [a, a];

the result will be incorrect. If your structure is like this, you might want to use Crockford's decycle or this (simpler) function which just replaces recursive references with nulls:

function decycle(obj, stack = []) {    if (!obj || typeof obj !== 'object')        return obj;        if (stack.includes(obj))        return null;
let s = stack.concat([obj]);
return Array.isArray(obj) ? obj.map(x => decycle(x, s)) : Object.fromEntries( Object.entries(obj) .map(([k, v]) => [k, decycle(v, s)]));}
//
let a = {b: [1, 2, 3]}a.b.push(a);
console.log(JSON.stringify(decycle(a)))

Javascript: TypeError: cyclic object value

This is typically because you are trying to serialize a JavaScript object that has properties that point to each other in a cycle.

In your example, newServiceObject.serviceCodeElemList points to a jQuery object which does have cycles in it: Its context property which points to a document object. A document object has pointers to DOM elements that have pointers back to the document through the ownerDocument property

    var jqueryObj = $('div');    console.log(jqueryObj.context); // Document object    console.log(jqueryObj.context.body.firstChild.ownerDocument); // Document object    
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div></div>

JSON.stringify cyclic object n^2

An ES6 Set object can keep track of objects visited directly. As you're traversing through the object, you put each object into the Set and then a simple objSet.has(obj) will tell if you've already encountered this object of not.

Work-arounds when that ES6 Set is not available usually involve adding a non-enumerable uniquely generated string key to each object so you can put that in a regular object map which is shown here in this ES6 Set polyfill.

Firebase.update failed: First argument contains a cyclic object value

Don't call model.save() if you're using Backbone.Firebase.Collection, simply edit the model using model.set() and the collection will be updated.



Related Topics



Leave a reply



Submit