My rest API returns with the following json content:
[{
"key": "apple",
"value": "green"
},
{
"key": "banana",
"value": "yellow"
}]
I am iterating through the list with this code:
this.props.json.map(row => {
return <RowRender key={id.row} row={row} />
}
It works because the content is displayed but on the web browser's console I can see an error:
map is not a function
I googled for it and I changed my code to this:
Array.prototype.slice.call(this.props.json).map(row => {
return <RowRender key={id.row} row={row} />
}
It works without any error but seems so complicated. Is that the correct way to do this job?
UPDATE
What I tried:
- JSON.parse(...).map: Unexpected end of JSON input
- JSON.parse(JSON.stringify(...)).map(...): data is displayed but I get an error: JSON.parse(...).map is not a function
- Array(...).map: Each child in array or iterator should have a unique key.
5 Answers
Use Object.entries() to get both the key and values, then give that to Map() to allow you to select your values by key.
let myMap = new Map(Object.entries(this.props.json));
in your code this.props.json is not an array, it's an array-like object and map is an array function. what your doing to solve this, is converting that array-like object into an array, with .slice()
a more elegant way to do this:
Array.from(this.props.json).map(row => <RowRender key={id.row} row={row} />)
You can do it very easily as @Gary mentioned in his answer:
From Map to JSON (string keys):
const personsJson = `{"1":{"firstName":"Jan","lastName":"Kowalski"},"2":{"firstName":"Justyna","lastName":"Kowalczyk"}}`;
const personsObject = JSON.parse(personsJson);
const personsMap = new Map(Object.entries(personsObject));
for (const key of personsMap.keys()) {
console.log(typeof key)
}
But there is one issue about which you have to be careful. Key of the map created in that way will always be a STRING. It will happen, because KEY of JSON object is always a STRING. So if your Map keys should be numbers then first you have parse keys of your object entries.
- From
JSONtoMap(number keys)::
const personsJson = `{"1":{"firstName":"Jan","lastName":"Kowalski"},"2":{"firstName":"Justyna","lastName":"Kowalczyk"}}`;
const personsObject = JSON.parse(personsJson);
const personObjectEntries = Object.entries(personsObject);
const personObjectEntriesNumberKeys = personObjectEntries.map(person => {
person[0] = parseInt(person[0]);
return person;
});
const personsMap = new Map(personObjectEntriesNumberKeys);
for (const key of personsMap.keys()) {
console.log(typeof key)
}
There is
person[0]because under 0 index there is the key of the object
let jsonMap = JSON.stringify([...map.entries()])
let myMap = new Map(JSON.parse(jsonMap));
You can copypaste this function: it would take JSON and return a Map of Maps:
It works with this JSON:
{
"data":{
"1":{
"color":"red",
"size":"big"
},
"2":{
"color":"red",
"size":"big"
},
"3":{
"color":"red",
"size":"big"
},
"4":{
"color":"red",
"size":"big"
},
"5":{
"color":"red",
"size":"big"
}
}
}
function jsonToMap(jsonString) {
var jsonObject = JSON.parse(jsonString);
var dataObject = jsonObject.data;
var dataMap = new Map(Object.entries(dataObject));
var resultMap = new Map();
for (const key of dataMap.keys()) {
console.log(key);
var keyMap = new Map(Object.entries(dataMap.get(key)));
resultMap.set(key, keyMap);
}
console.log("done!");
return resultMap;
}