I have a JSON
object that contains array of objects, inside each of them there is key:value
object with 2 entries and each entry has it's own fields.
[
{
"application": {
"some key": "some value 1",
"another key": "another value 1"
},
"data": [
{
"some key": "value",
"another key": "value"
},
{
"some key": "value",
"another key": "value"
},
{
"some key": "value",
"another key": "value"
},
{
"some key": "value",
"another key": "value"
}
]
},
{
"application": {
"some key": "some value 2",
"another key": "another value 2"
},
"data": [
{
"some key": "value",
"another key": "value"
},
{
"some key": "value",
"another key": "value"
},
{
"some key": "value",
"another key": "value"
},
{
"some key": "value",
"another key": "value"
}
]
}
]
I'm trying to (1) map
the array and then (2) use reduce
in order to extract some values that I need from that key:value
objects.
const createGroupedData = (data) => {
const promises = data.reduce(async (acc, obj) => {
const month = moment.unix(obj.userComment.lastModified.seconds).format('MMMM');
const rating = obj.userComment.starRating.toString();
if (!acc[month]) {
acc[month] = {};
}
if (!acc[month][rating]) {
acc[month][rating] = [];
}
acc[month][rating].push(obj);
return acc;
}, {});
return Promise.all(promises);
}
const createGroupedObject = async (reviewObjects) => {
const appPromises = reviewObjects.map(async (reviewObject, index) => {
return {
application: reviewObject.application,
data: await createGroupedData(reviewObject.data)
};
});
return Promise.all(appPromises);
};
// Do the magic!
createGroupedObject(data);
I am getting an error of:
TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
From this row:
Anyone know why?
From what i understand the purpose of createGroupedData
is supposed to go over the data array and group related values in the array to a Map. essentially all values belonging to the same key will be will be put in an array as values for that key.What i don't understand is why your reduce function is asynchronous given the data is passed to the function when its already resolved.
const createGroupedData = (data) => {
//remove async key word since there is no where
//in the body where the reducer is waiting on some promise to resolve
const promises = data.reduce( (acc, obj) => {
const month = moment.unix(obj.userComment.lastModified.seconds).format('MMMM');
const rating = obj.userComment.starRating.toString();
if (!acc[month]) {
acc[month] = {};
}
if (!acc[month][rating]) {
acc[month][rating] = [];
}
acc[month][rating].push(obj);
return acc;
//use new Map() to create a Map instead of relying on an object as a Map
}, new Map());
return promises;
}
const createGroupedObject = async (reviewObjects) => {
const appPromises = reviewObjects.map(async (reviewObject, index) => {
return {
application: reviewObject.application,
//remove await createGroupedData is not asynchronous
data: createGroupedData(reviewObject.data)
};
});
//this call will fail to for the same reason
return Promise.all(appPromises);
};
essentially noting from what you are trying to accomplish requires any promises .This might be obvious but only use them in situations where your function needs to wait for some call to complete .In this case you already have the data and all you doing is grouping it .There are no network calls or functions that need to complete in between these steps therefore no need for promises . As for the error .That is caused because Promises.all() expects and array input and you are giving it an object