How to JSON.Stringify an Es6 Map

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);

How to stringify an object of the type Map

Preface: Class names should start with an uppercase character, so I've changed test to Test in the below.

Since Map isn't stringify-able by default, you have at least three choices:

  1. Implement toJSON on your Test class and return an object with a replacement for children (probably an array of arrays), or

  2. Implement a subclass of Map that has toJSON and use that in Test

  3. Implement a replacer that you use with JSON.stringify that handles Map instances.

While #1 works, it means you have to edit your toJSON method every time you add or remove properties from Test, which seems like a maintenance issue:

class Test {
name: string
children: Map<string, string> = new Map()
constructor() {
this.name = 'KIANA'
this.children.set('name', 'OTTO')
}
toJSON() {
return {
name: this.name,
children: [...this.children.entries()]
}
}
}
var t = new Test()
console.log(JSON.stringify(t))

Live Example:

class Test {  name/*: string*/  children/*: Map<string, string>*/ = new Map()  constructor() {    this.name = 'KIANA'    this.children.set('name', 'OTTO')  }  toJSON() {    return {      name: this.name,      children: [...this.children.entries()]    }  }}var t = new Test()console.log(JSON.stringify(t))

Convert Map to JavaScript object

You could loop over the map and over the keys and assign the value

function createPaths(aliases, propName, path) {    aliases.set(propName, path);}
var map = new Map(), object = {};
createPaths(map, 'paths.aliases.server.entry', 'src/test');createPaths(map, 'paths.aliases.dist.entry', 'dist/test');
map.forEach((value, key) => { var keys = key.split('.'), last = keys.pop(); keys.reduce((r, a) => r[a] = r[a] || {}, object)[last] = value;});
console.log(object);

JavaScript - Map + Stringify data

After parsing the JSON, check if it's an array. If not, put it in an array.

var jsArray = JSON.parse(EventData);
if (!Array.isArray(jsArray)) {
jsArray = [jsArray];
}

How could i turn a Map() into a string as it is, WITHOUT it becoming a json object in js/ts

if you need to display object like { 'key' => 'value' } and not ":" exists on key or value you can do

let data = {'key' : 'value'}
JSON.stringify(data).replace(":", " => ")

Create json string from js Map and String

You can write a short conversion function to make a map into an object that can be stringified.

console.clear()
function mapToObj(map){ const obj = {} for (let [k,v] of map) obj[k] = v return obj}
const myMap = new Map();myMap.set("key1", "value1");myMap.set("key2", "value2");myMap.set("key3", "value3");
const myString = "string value"
const myJson = {};myJson.myMap = mapToObj(myMap);myJson.myString = myString;const json = JSON.stringify(myJson);
console.log(json)

JSON.stringify not working in my map method in template literals

i think the issue is here,

secondary={`${props.movie.overview} Released in ${props.movie.release_date ? props.movie.release_date.substr(0, 4) : 'N/A'}
${openMovieDbRatings ? openMovieDbRatings.map((rating: any) => <div>{JSON.stringify(rating.Source)}: {JSON.stringify(rating.Value)}</div>) : 'No Reviews'}
Rated: ${openMovieDbData['Rated'] ? openMovieDbData['Rated'] : 'N/A'}
`}

#1: (main)

${openMovieDbRatings
? openMovieDbRatings.map((rating: any) =>
<div>{JSON.stringify(rating.Source)}: {JSON.stringify(rating.Value)}</div>
)
: 'No Reviews'}

You are mapping openMovieDbRatings and making em ReactElements (aka Objects) by wrapping those inside divs. But, Then u directly pass them to string. This is causing the [object object] thing

#2:

The Rating Object,

"Ratings": [{
"Source": "Internet Movie Database",
"Value": "8.3/10"
}, {
"Source": "Rotten Tomatoes",
"Value": "78%"
}, {
"Source": "Metacritic",
"Value": "68/100"
}],

Here, The Rating Value & Source are strings. So, it unnecessary to JSON.stringify them,

<div>{JSON.stringify(rating.Source)}: {JSON.stringify(rating.Value)}</div>

My Solution,

<ListItemText
primary={props.movie.title}
secondary={
<>
{props.movie.overview} Released in{' '}
{props.movie.release_date
? props.movie.release_date.substr(0, 4)
: 'N/A'}{' '}
{openMovieDbRatings
? openMovieDbRatings.map((rating: any) => (
<div>
{rating.Source}: {rating.Value}
</div>
))
: 'No Reviews'}
Rated:{' '}
{openMovieDbData['Rated'] ? openMovieDbData['Rated'] : 'N/A'}
</>
}
/>

Simply, use React.Fragments.



Related Topics



Leave a reply



Submit