How do you JSON.stringify an ES6 Map?
Both JSON.stringify
and JSON.parse
support a second argument. replacer
and reviver
respectively. With replacer and reviver below it's possible to add support for native Map object, including deeply nested values
function replacer(key, value) { if(value instanceof Map) { return { dataType: 'Map', value: Array.from(value.entries()), // or with spread: value: [...value] }; } else { return value; }}
function reviver(key, value) { if(typeof value === 'object' && value !== null) { if (value.dataType === 'Map') { return new Map(value.value); } } return value;}
Usage:
const originalValue = new Map([['a', 1]]);const str = JSON.stringify(originalValue, replacer);const newValue = JSON.parse(str, reviver);console.log(originalValue, newValue);
Deep nesting with combination of Arrays, Objects and Maps
const originalValue = [ new Map([['a', { b: { c: new Map([['d', 'text']]) } }]])];const str = JSON.stringify(originalValue, replacer);const newValue = JSON.parse(str, reviver);console.log(originalValue, newValue);
You can't directly stringify the Map
instance as it doesn't have any properties, but you can convert it to an array of tuples:
jsonText = JSON.stringify(Array.from(map.entries()));
For the reverse, use
map = new Map(JSON.parse(jsonText));
You can't.
The keys of a map can be anything, including objects. But JSON syntax only allows strings as keys. So it's impossible in a general case.
My keys are guaranteed to be strings and my values will always be lists
In this case, you can use a plain object. It will have these advantages:
- It will be able to be stringified to JSON.
- It will work on older browsers.
- It might be faster.