Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you JSON.stringify an ES6 Map?

I'd like to start using ES6 Map instead of JS objects but I'm being held back because I can't figure out how to JSON.stringify() a Map. My keys are guaranteed to be strings and my values will always be listed. Do I really have to write a wrapper method to serialize?

like image 794
rynop Avatar asked Mar 16 '15 19:03

rynop


People also ask

Can you JSON Stringify a map?

You can't. The keys of a map can be anything, including objects. But JSON syntax only allows strings as keys.

How do I Stringify a JSON object?

Stringify a JavaScript ObjectUse the JavaScript function JSON. stringify() to convert it into a string. const myJSON = JSON. stringify(obj);

What is JSON Stringify () method?

The JSON. stringify() method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.

Can JSON have a map?

You can map the data types of your business model into JSON by using the examples. Data in JSON is either an object or an array. A JSON object is an unordered collection of names and values. A JSON array is an ordered sequence of values.


4 Answers

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);
like image 119
Pawel Avatar answered Oct 06 '22 15:10

Pawel


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));
like image 32
Bergi Avatar answered Oct 06 '22 15:10

Bergi


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.
like image 67
Oriol Avatar answered Oct 06 '22 15:10

Oriol


While there is no method provided by ecmascript yet, this can still be done using JSON.stingify if you map the Map to a JavaScript primitive. Here is the sample Map we'll use.

const map = new Map();
map.set('foo', 'bar');
map.set('baz', 'quz');

Going to an JavaScript Object

You can convert to JavaScript Object literal with the following helper function.

const mapToObj = m => {
  return Array.from(m).reduce((obj, [key, value]) => {
    obj[key] = value;
    return obj;
  }, {});
};

JSON.stringify(mapToObj(map)); // '{"foo":"bar","baz":"quz"}'

Going to a JavaScript Array of Objects

The helper function for this one would be even more compact

const mapToAoO = m => {
  return Array.from(m).map( ([k,v]) => {return {[k]:v}} );
};

JSON.stringify(mapToAoO(map)); // '[{"foo":"bar"},{"baz":"quz"}]'

Going to Array of Arrays

This is even easier, you can just use

JSON.stringify( Array.from(map) ); // '[["foo","bar"],["baz","quz"]]'
like image 37
NO WAR WITH RUSSIA Avatar answered Oct 06 '22 14:10

NO WAR WITH RUSSIA