Trying to asynchronously filter and transform an array of objects that I receive from my backend. I'm using Redux with React to manage store. Here's what I have now in my slice.js
:
...
export const getData = createAsyncThunk('foo/bar', async (address, thunkAPI) => {
try {
//returns an array of objects [{}, {}, ...]
const allData = JSON.parse(await myService.getAllData(address));
let newData = [];
allData.forEach(async (data) => {
if(*some filtering logic here*) {
newData.push(await (fetch(data.uri).then(response => response.json())));
}
});
return newData;
} catch (error) {
//handle error
}
});
However, my newData
array seems to be unpushable/marked as unextensible. It gives the error
Uncaught (in promise) TypeError: Cannot add property 0, object is not extensible
at Array.push (<anonymous>)
Some of the other solutions to this error (React : cannot add property 'X', object is not extensible, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible) all mention React props/editing state variables, but I can't figure out why I cannot push to an empty array newData
.
CodePudding user response:
You cannot do async
in forEach
, so you need a plain old for loop
try {
const allData = JSON.parse(await myService.getAllData(address));
const newData = []; // not reassigning, use const
for (let i = 0, n = allData.length; i < n; i) {
if (*some filtering logic here*) {
newData.push(await (fetch(data.uri).then(response => response.json())));
}
}
return newData;
}
This should work
CodePudding user response:
Hey There so with regards to your question here is another way you could achieve what you are looking to achieve let me know if this helps you out for future too maybe
try {
//returns an array of objects [{}, {}, ...]
const allData = JSON.parse(await myService.getAllData(address));
let newData = [];
// this will be an array of unresolved promises and then you can have them run in parallel with the promise all below
const promises = allData.map((objectOfData) => fetch(objectOfData.uri))
//this data will be the results
const data = Promise.all(promises)
//do with the data what you want
data.forEach((item) => {
if(*some filtering logic here*) {
newData.push(item);
}
})
return newData;
} catch (error) {
//handle error
}