Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I print a circular structure in a JSON-like format?

I have a big object I want to convert to JSON and send. However it has circular structure. I want to toss whatever circular references exist and send whatever can be stringified. How do I do that?

Thanks.

var obj = {   a: "foo",   b: obj } 

I want to stringify obj into:

{"a":"foo"} 
like image 589
Harry Avatar asked Jul 23 '12 16:07

Harry


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.

What is a circular JSON?

The circular structure you have is not in JSON, but in the object that you are trying to convert to JSON. Circular structures come from objects which contain something which references the original object. JSON does not have a manner to represent these.

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.


2 Answers

In Node.js, you can use util.inspect(object). It automatically replaces circular links with "[Circular]".


Albeit being built-in (no installation is required), you must import it

import * as util from 'util' // has no default export import { inspect } from 'util' // or directly // or  var util = require('util') 
To use it, simply call
console.log(util.inspect(myObject)) 

Also be aware that you can pass options object to inspect (see link above)

inspect(myObject[, options: {showHidden, depth, colors, showProxy, ...moreOptions}]) 


Please, read and give kudos to commenters below...

like image 157
Erel Segal-Halevi Avatar answered Oct 08 '22 01:10

Erel Segal-Halevi


Use JSON.stringify with a custom replacer. For example:

// Demo: Circular reference var circ = {}; circ.circ = circ;  // Note: cache should not be re-used by repeated calls to JSON.stringify. var cache = []; JSON.stringify(circ, (key, value) => {   if (typeof value === 'object' && value !== null) {     // Duplicate reference found, discard key     if (cache.includes(value)) return;      // Store value in our collection     cache.push(value);   }   return value; }); cache = null; // Enable garbage collection 

The replacer in this example is not 100% correct (depending on your definition of "duplicate"). In the following case, a value is discarded:

var a = {b:1} var o = {}; o.one = a; o.two = a; // one and two point to the same object, but two is discarded: JSON.stringify(o, ...); 

But the concept stands: Use a custom replacer, and keep track of the parsed object values.

As a utility function written in es6:

// safely handles circular references JSON.safeStringify = (obj, indent = 2) => {   let cache = [];   const retVal = JSON.stringify(     obj,     (key, value) =>       typeof value === "object" && value !== null         ? cache.includes(value)           ? undefined // Duplicate reference found, discard key           : cache.push(value) && value // Store value in our collection         : value,     indent   );   cache = null;   return retVal; };  // Example: console.log('options', JSON.safeStringify(options)) 
like image 45
Rob W Avatar answered Oct 08 '22 01:10

Rob W