When I get Uncaught TypeError: Converting circular structure to JSON on a large structure it can be very difficult to find out where exactly the circular reference is.
Is there a simple way to find/debug the circular element in the data structure?
I haven't found a simple method to do it, other people seem to be suggesting using custom replacer function in JSON.stringify to control which properties have been visited.
I've attempted to write such replacer:
function detector(obj) { function collector (stack, key, val) { var idx = stack[stack.length - 1].indexOf(key); try { var props = Object.keys(val); if (!props.length) throw props; props.unshift({idx : idx}); stack.push(props); } catch (e) { while (!(stack[stack.length - 1].length - 2)) { idx = stack[stack.length -1][0].idx; stack.pop(); } if (idx + 1) { stack[stack.length - 1].splice(idx, 1); } } return val; } var stack = [[]]; try { JSON.stringify(obj, collector.bind(null, stack)); } catch (e) { if (e.message.indexOf('circular') !== -1) { var idx = 0; var path = ''; var parentProp = ''; while(idx + 1) { idx = stack.pop()[0].idx; parentProp = stack[stack.length - 1][idx]; if (!parentProp) break; path = '.' + parentProp + path; } console.log(path); } } } What it does is while traversing the JSON tree (probably tree :)) it collects names of properties which have been visited and as soon as JSON.stringify detects circular reference and throws, 'stack' variable will contain a trace of which subtree it was traversing. And it logs this path to console.
However, this is not a heavily tested solution.
console.dir()the object and then interactively poke around in the browser console.