JSON does not have an undefined
value, but we could write a workaround:
Preserving nested undefined values
I wrote 2 functions that internally uses JSON.stringify
and JSON.parse
and preserves nested undefined
values using a value placeholder:
Equivalent to JSON.stringify
:
/**
* Serialize a POJO while preserving nested `undefined` values.
*/
function serializePOJO(value, undefinedPlaceholder = "[undefined]") {
const replacer = (key, value) => (value === undefined ? undefinedPlaceholder : value);
return JSON.stringify(value, replacer);
}
Equivalent to JSON.parse
:
/**
* Deserialize a POJO while preserving nested `undefined` values.
*/
function deserializePOJO(value, undefinedPlaceholder = "[undefined]") {
const pojo = JSON.parse(value);
if (pojo === undefinedPlaceholder) {
return undefined;
}
// Function that walks through nested values
function deepIterate(value, callback, parent, key) {
if (typeof value === "object" && value !== null) {
Object.entries(value).forEach(([entryKey, entryValue]) => deepIterate(entryValue, callback, value, entryKey));
} else if (Array.isArray(value)) {
value.forEach((itemValue, itemIndex) => deepIterate(itemValue, callback, value, itemIndex));
} else if (parent !== undefined) {
callback(value, parent, key);
}
}
// Replaces `undefined` placeholders
deepIterate(pojo, (value, parent, key) => {
if (value === undefinedPlaceholder) {
parent[key] = undefined;
}
});
return pojo;
}
Usage:
const source = {
foo : undefined,
bar : {
baz : undefined
}
};
const serialized = serializePOJO(source);
console.log("Serialized", serialized);
// '{"foo":"[undefined]","bar":{"baz":"[undefined]","qux":[1,"[undefined]",2]}}'
const deserialized = deserializePOJO(serialized);
console.log("Deserialized", deserialized);
Works with both object entries and array items.
The downside is that you have to choose an appropriate placeholder that will not be mistaken via a "real" source value. The placeholder is customizable via the optional undefinedPlaceholder
argument.
This is specially useful to store POJO in browser local storage ;)
See also:
"undefined"
or perhapsnull
or an empty string""
. How would you prefer it? – Brooksstring
,number
,object
,array
,true
,false
ornull
. Note thatundefined
isn't an option. – Baseman{ name:"boda", email:undefined, country:"africa" }
– Marketplace