Search code examples
javascriptreactjsreduxreact-reduxredux-thunk

How do I map an array of objects to different objects (with different properties) in a Redux Slice?


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.


Solution

  • 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