How to Print a Circular Structure in a JSON-like Format: A Detailed Guide

Circular Structures in JavaScript are self-referencing objects or functions that, when printed in a JSON-like format, throw a Type Error: “TypeError: Converting circular structure to JSON“. In this article, we will understand what circular structures are, how to print these structures and the reason behind them throwing an error.

Understanding Circular Structures

An object in JavaScript might contain properties of various types, including string, integer, boolean and array.

Let’s consider the below object:

const obj = {
  name: "Dillion",
  isDev: true,
  hobbies: ["singing", "writing"],
  age: 100,
}

The above object is an example of an object with properties with normal datatypes. But there might be a case where a property references an object itself. Such references are known as circular references.

Now let’s add a property itself to the above object which will reference to the object itself:

const obj = {
  name: "Dillion",
  isDev: true,
  hobbies: ["singing", "writing"],
  age: 100,
};

obj.itself = obj;

Now one might be wondering what the outcome of the obj.itself be. We can output this property using:

console.log(obj.itself);

The outcome of the above code will be as follows:

Output of Circular reference Property
Output of Circular Reference Property

In the console, we obtained the value of itself as [Circular*1]. This represents that the property references back to the object and is a circular reference. In the console, when we try to print this object containing circular property then that references to itself and will result in an endlessly nested object.

However, we can use the property with circular reference that is itself any number of times and access any other property of the same object. This can be illustrated as follows:

console.log(obj.itself.itself.itself.itself.name);

Using the above line of code, we will obtain the value of the property name in the console.

Problem in Printing Circular Structures

We observed how we can reference the object itself using the property of the object thus creating a circular reference. Now we wish to print this object in a JSON-like format for which we will use the stringify method.

In order to print the object in JSON-like format we will write the following piece of code:

const obj = {
  name: "Dillion",
  isDev: true,
  hobbies: ["singing", "writing"],
  age: 100,
};

const stringified=JSON.stringify(obj);
console.log(stringified);

The above code was written without the circular reference thus the output obtained will be:

Output of Object in JSON Format
Output of Object in JSON Format Without Circular Reference

Now the question is what will happen if we try to print the object in a similar format but when it contains a circular reference.

Consider the following code:

const obj = {
  name: "Dillion",
  isDev: true,
  hobbies: ["singing", "writing"],
  age: 100,
};

obj.itself = obj;

const stringified=JSON.stringify(obj);
console.log(stringified);

The following lines of error are observed in the console window while printing a circular structure in a JSON-like format:

Output of Object Containing Circular Reference in JSON Format
Output of Object Containing Circular Reference in JSON Format

From the above console window, we observe that on printing the object with a circular reference it throws a TypeError.

The reason behind this error is that we are trying to stringify a circular reference which is going to be an infinite stringification process.

JSON stringify tried going through this object and the following happens: stringify method goes from the first property in obj which is name to the last property itself. When it gets to itself, it stringifies the properties of this object. The value of the itself object is the obj object, so stringify goes through from name to itself again. By coming across itself, it has to go through the entire object again. And the process goes on.

Printing Circular Structure in JSON Format

When trying to print the object with circular reference in a JSON-like format we entered an infinite loop of the stringification process because the stringify method didn’t know when to stop. Each time it encountered the itself property the entire process of object stringification started again and it goes on forever.

Thus the main issue with stringifying the object is that when we come across the itself property the process starts all over again. Therefore one way to resolve this problem can be to avoid coming across this property with circular reference.

Serialization is a way to resolve this issue. In this method, we serialize the object to remove some properties from the object and thus successfully print the object in JSON format. This process removes properties that are not useful for us or the ones that cause errors. Here we are concerned with removing properties that cause error that is, the properties that reference the object itself.

Here is an illustration of the serialization method:

const obj = {
  name: "Dillion",
  isDev: true,
  hobbies: ["singing", "writing"],
  age: 100,
};

obj.itself = obj

function replacer(key, value) {
  if(key === 'itself') {
    return null
  }

  return value
}

const stringified = JSON.stringify(obj, replacer)

console.log(stringified)

In the above code, we have used the replacer function to modify itself property that is whenever the stringify method comes across this property NULL is returned instead of the reference to the object. In replacer function, we check for the key itself and return NULL as its value otherwise return the original value.

In this way, JSON.stringify() is able to convert the object to JSON-like format successfully without entering an infinite loop and throwing an error thus resolving the problem of printing the circular structure.

Output:

Output of Circular Structure using Serialization
Output of Circular Structure using Serialization

Summary

Circular Structures are objects that contain property with a circular reference. Circular Reference means a property of the object where it references the object itself. When we try printing such an object or structure in JSON-like format it throws an error since stringification of an object with a circular reference is an infinite process. Therefore, we use serialization as a way to overcome this error. Through this method we try to avoid those properties that cause the error, here are the ones with a circular reference. Now whenever we encounter the property with a circular reference, NULL is returned otherwise the stringify method returns the value of the property.

References

Khushi Soni
Khushi Soni
Articles: 3