Skip to content

Instantly share code, notes, and snippets.

@ORESoftware
Last active December 8, 2018 23:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ORESoftware/10bd74e27728a2aa764df4d6c6ecada8 to your computer and use it in GitHub Desktop.
Save ORESoftware/10bd74e27728a2aa764df4d6c6ecada8 to your computer and use it in GitHub Desktop.
Limitation of current safe stringify routines

We are aware that JSON.stringify cannot handle circular refs. There are some solutions circulating online, for example the safeStringify method below, which has the most upvotes here: https://stackoverflow.com/a/11616993/1223975

The function in the link above is below:

const safe = require('@oresoftware/safe-stringify');

const v = {foo:'bar'};   // this is our funky object with circular refs
v.mmm = {zoom:2};
v.mmm.x = v; 

const safeStringify = function(o){
  const cache = [];
  return JSON.stringify(o, function(key, value) {
    if (typeof value === 'object' && value !== null) {
      if (cache.indexOf(value) !== -1) {
        // Duplicate reference found
        try {
          // If this value does not reference a parent it can be deduped
          return JSON.parse(JSON.stringify(value));
        } catch (error) {
          // discard key if value cannot be deduped
          return;
        }
      }
      // Store value in our collection
      cache.push(value);
    }
    return value;
  });
};


console.log(safeStringify([v,v,v]));    // not good
console.log(safe.stringify([v,v,v]));   // not good
console.log(safe.stringifyDeep([v,v,v]));  // works now

It turns out, the answer with hundreds of upvotes on SO is a good but imperfect solution. The solution given by safe.stringifyDeep is more ideal. It copys the object first, and then stringifies it. The trick is to use not just one cache, but a cache for each node in the object tree.

However, stringifyDeep is not production ready, please don't use it yet, without improving it and making sure it works for you.

enjoy the @oresoftware/safe-stringify library https://github.com/ORESoftware/safe-stringify

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment