Transforming JSON
JSON.stringify
ignores property that are not enumerable and not supported (function
and undefined
).
Input value should be an object, otherwise, JSON.stringify
treats it as an object with empty key whose value is the said input. Unsupported value in array results in null
. JSON.stringify uses the toJSON
method is one is found on the object.
To transform value in JSON.stringify
before running the actual function (assuming the object does not have a toJSON
method), you can provide a callback function as the second parameter to the function.
JSON.parse
also takes a second parameter of a callback function, it is executed after parsing has been completed.
Such a function has the following signature:
function nodeVisitor(key, value) {
// this refers to root
// if value is not an object, then this is object with empty key, and value being the value.
// return undefined and node is removed
// otherwise node is replaced with whatever that is returned
}
Written by Angela
Related protips
2 Responses
One might wonder of what use this is. I mean, we've gotten by so far without providing any callbacks, right? One use case that I find myself using the optional callbacks are when a cycle is defined in the JSON object. Consider the following JSON:
let o = {
k1: 'key1',
k2: o
};
You'll notice that k2
points back to the original object, o
. Some platforms will automatically detect this and eliminate the cyclic key (k2
in this case).
Alternatively, you could provide a callback to stringify
to detect said cycle and remove the key yourself:
let seen = [];
JSON.stringify(o, (key, val) => {
if (val && typeof(val) === 'object') {
if (seen.includes(val)) {
return; // Uh-oh, a cycle
}
// Record this value to ensure we avoid serializing it again
seen.push(val);
}
return val;
});
Note: I didn't actually run the code above, so errors may exist.
It could also be used to eliminate unwanted objects, such as DOM nodes, from the data structure.