New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optionally, replace circular references with the key it points to #1
Comments
Not something I need, but a good pull request would be welcomed. |
@binyamin your example does not produce a circulare reference, const foo = {a: true};
foo.b = foo;
foo.c = foo.b;
console.log(safeStringify(foo, {trace: true})); There are multiple correct outputs we can expect: Output 1: {"a":true,"b":"[Circular *]","c":"[Circular *]"} Output 2: {"a":true,"b":"[Circular *]","c":"[Circular *b]"} In the first output, we resolve from Another case which has beeen retrieved from the tests is the following: const fixture = {
a: true,
};
fixture.b = fixture;
console.log(safeStringify({x: fixture, y: fixture}, optionsWithTrace)); A possible output would be: {"x":{"a":true,"b":"[Circular *x]"},"y":"[Circular *x]"} Here both keys I'm going to push a PR to track a possible solution. Due to the nature of circular references and the |
If anyone wants to work on this, see the initial attempt and feedback here: #3 |
I learned about the content of this PR - #3. According to the latest code, the latest implementation of the trace function is shown below: function safeStringifyReplacer(seen, trace) {
return function (key, value) {
if (value !== null && typeof value === 'object') {
if (seen.has(value)) {
return trace ? `[Circular *${seen.get(value)}]` : '[Circular]';
}
seen.set(value, key);
const newValue = Array.isArray(value) ? [] : {};
for (const [key2, value2] of Object.entries(value)) {
newValue[key2] = safeStringifyReplacer(seen, trace)(key2, value2);
}
seen.delete(value);
return newValue;
}
return value;
};
}
export default function safeStringify(object, {indentation, trace} = {}) {
const seen = new WeakMap();
return JSON.stringify(object, safeStringifyReplacer(seen, trace), indentation);
} Assuming there is an object: const obj = {
a: 'a',
b: {
prop1: 'prop1',
b: {}
}
}; Set circular reference: obj.b.b.f = obj.b Run
If the circular reference set above is another obj.b.b.f = obj.b.b There is no difference in the results of running the So I think when opening trace, the key should not be directly displayed, but the path of the key should be displayed. The path of the key, just like when the second parameter of Lodash's get function is a string. var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, 'a[0].b.c'); The expected outcome should be the following:
What is your opinion? |
I expect it to show the full path (the second one). You could use this as inspiration: https://github.com/sindresorhus/decircular/blob/main/index.js |
I like this library — decircular. Although I will not invent from scratch, I have learned a lot from your code, and I am grateful from the bottom of my heart. I have one last question that I would like to ask you., regarding the case where the access path is a number: // property a is an array
const obj = {
"a": [
{
"b": {
"c": 3
}
}
]
}
// or property a is an object, but key is a number
const obj = {
"a": {
0: {
"b": {
"c": 3
}
}
}
} If you want to read the value of attribute In decircular
The reference path output in the log is |
Currently, circular references are each replaced with the string
[Circular]
. It would be helpful to identify which key the circular reference points to.The text was updated successfully, but these errors were encountered: