'use JSON.parse reviver to force value of undefined in resulting object rather than cause property to be omitted
JSON.parse takes serialized JSON as an argument and deserializes it. The second (optional) argument is a reviver function, taking a key and value and returning the replacement value in the deserialized object. It is documented behavior that the reviver, if it returns undefined or nothing, the property in question will be omitted from the resulting deserialized object.
I have a situation where I would like the property in question to be INCLUDED in the resulting deserialized object with the value of undefined.
So, for example, the following is currently true:
JSON.parse(JSON.stringify({a: 1, b:2}), (k, v) => v===2 ? undefined : v);
// result of this is {a:1}, as is documented/expected.
But what if I actually want the result to be
{a:1, b:undefined}
Is there any way to write the reviver to do this?
I specifically don't want to iterate through the object again after the deserialization, so please don't suggest that as a solution. Also I specifically don't want b to be set as null. I really want it to be present as a property with the value undefined.
It may simply not be possible, but I'm hoping someone has a nifty idea!
FIRST EDIT:
First suggestion was great try, but I also need it to work in deep structures, so the following:
JSON.parse(JSON.stringify({
a: 1,
b:{
c: 1,
d: 2,
e: [
1,
2,
{
f: 1,
g: 2
},
4
]
}
}), (k, v) => v===2 ? undefined : v);
should in my ideal world yield:
{
a: 1,
b:{
c: 1,
d: undefined,
e: [
1,
undefined,
{
f: 1,
g: undefined
},
4
]
}
}
Solution 1:[1]
I doubt this can be done with a simple reviver and JSON.parse.
I don't know if this will satisfy your constraints, and it's ugly as sin, but here's an approach: wrap JSON.parse in something that stores the undefined keys from your reviver and adds them back at the end. This does not entail iterating your object again, which you explicitly rejected, but it does iterate the list of undefined keys:
const myParse = (obj, reviver) => {
if (typeof reviver !== 'function') {
return JSON.parse(obj)
}
const undefs = []
const rev = (k, v) => {
const val = reviver(k, v)
if (typeof val === 'undefined') {
undefs.push(k)
}
return val;
}
const ret = JSON.parse(obj, rev)
undefs.forEach(k => ret[k] = undefined)
return ret
}
const result = myParse(
JSON.stringify({a: 1, b:2}),
(k, v) => v===2 ? undefined : v
)
console.log(result)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Scott Sauyet |
