1

I want to serialize circular reference to JSON

This is the part generating the JSON array and it causes a circular reference because it creates a child inside an element and I want to display the result.

const  mappedData = this.state.treeData
    .filter(data => data.title === "Category")
     .map(categ => {
      const { id, title, children, subtitle, type } = categ;

      function getChildren(children) {
        return children
          ? children.map(child => {
              if (child.title === "Item" || child.title === "Group") {
                const data = {
                  id: child.id,
                  name: child.subtitle,
                  type: child.type,
                  children: getChildren(child.children),
                  child_id: child.children
                    ? child.children.map(child => child.id)
                    : []
                };
                if (data.children.length === 0) delete data.children;
                if (data.child_id.length === 0) delete data.child_id;

                return data;
              } else {
                return {
                  id: child.id,
                  name: child.subtitle,
                  type: child.type
                };
              }
            })
          : [];
      }

      const data = {
        id: id,
        name: subtitle,
        type: type,
        children: getChildren(children),
        child_id: children ? children.map(child => child.id) : []
      };

      if (data.children.length === 0) delete data.children;
      if (data.child_id.length === 0) delete data.child_id;

      return data;
    });

The HTML part that calls the stringify method

<div className="json">
            <p> {JSON.stringify(mappedData)}</p>
</div>

I found a Replacer that it works but the JSON result is too long for what I need

const getCircularReplacer = () => {
  const seen = new WeakSet();
  return (key, value) => {
    if (typeof value === "object" && value !== null) {
      if (seen.has(value)) {
        return;
      }
      seen.add(value);
    }
    return value;
  };
};

JSON.stringify(circularReference, getCircularReplacer());

And here's the result :

[{"id":"7a69fc68","name":{"type":"input","key":null,"ref":null,"props":{"className":"inputSubs","type":"text","placeholder":"Category Name"},"_owner":{"tag":1,"key":null,"stateNode":{"props":{},"context":{},"refs":{},"updater":{},"notificationAlert":{"current":{"props":{},"refs":{"notifications":{"__reactInternalInstance$6qqi1p3qi9b":{"tag":5,"key":null,"elementType":"div","type":"div","return":{"tag":1,"key":null,"return":{"tag":5,"key":null,"elementType":"div","type" .. etc

Any Help ?

  • The circular reference is most likely in your `mappedData`, so this is not really a ReactJS issue. You need to use a different replacer: https://stackoverflow.com/a/11616993/1540350 – Martin Braun Jul 22 '19 at 13:15
  • can you provide a mappedData object that shows the problem? – Will Jenkins Jul 22 '19 at 13:16
  • it crashes when I drag the element that add data to JSON – PHANTOM Xif Jul 22 '19 at 13:26
  • You shouldn't use a replacer at all. You cannot use this type of references inside JSON. Size of JSON shouldn't be an issue, trust HTTP compression to remove duplicites. – Sulthan Jul 22 '19 at 13:38
  • But it's not working without the replacer or maybe it's another problem causing this issue ? – PHANTOM Xif Jul 22 '19 at 13:49

0 Answers0