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:
Implement
toJSON
on yourTest
class and return an object with a replacement forchildren
(probably an array of arrays), orImplement a subclass of
Map
that hastoJSON
and use that inTest
Implement a replacer that you use with
JSON.stringify
that handlesMap
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
Pass Props to Parent Component in React.Js
How to Remove All Line Breaks from a String
How to Share $Scope Data Between States in Angularjs Ui-Router
Browsers, Time Zones, Chrome 67 Error (Historic Timezone Changes)
Access Control Request Headers, Is Added to Header in Ajax Request with Jquery
How to Add External Js Scripts to Vuejs Components
Passing an Array as a Function Parameter in JavaScript
When Should I Use Jquery's Document.Ready Function
Jquery Get Specific Option Tag Text
How to Gain Access to the Closure of a Function
How to Redirect with JavaScript
Check/Uncheck Checkbox with JavaScript
Recurring Events in Fullcalendar
How to Pass Data from a Page to Another Page Using React Router
How to Use Async/Await at the Top Level
Define Global Variable with Webpack