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
JavaScript Math, Round to Two Decimal Places
Jquery (Or Pure Js) Simulate Enter Key Pressed for Testing
How to Set Multiple CSS Styles in JavaScript
Doesn't JavaScript Support Closures with Local Variables
Chrome Extension - Sendresponse Not Waiting for Async Function
Map and Filter an Array at the Same Time
Js:Convert Array of Strings to Array of Objects
Adding Console.Log to Every Function Automatically
Casting Plain Objects to Class Instances in JavaScript
ASP.NET Postback with JavaScript
Angularjs - Any Way for $Http.Post to Send Request Parameters Instead of JSON
When Is the Body of a Promise Executed
Get the Index of the Object Inside an Array, Matching a Condition
Filtering Array of Objects with Arrays Based on Nested Value
Object Method with Es6/Bluebird Promises
How to Loop Through All Dom Elements on a Page