Intentando filtrar y transformar de forma asincrónica una matriz de objetos que recibo de mi backend. Estoy usando Redux con React para administrar la tienda. Esto es lo que tengo ahora en mi 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 } }); Sin embargo, mi newData matriz de datos parece ser imposible de empujar/marcar como no extensible. da el error
Uncaught (in promise) TypeError: Cannot add property 0, object is not extensible at Array.push (<anonymous>) Algunas de las otras soluciones a este error ( Reaccionar: no se puede agregar la propiedad 'X', el objeto no es extensible , https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible ) todas mencione React props/editing state variables, pero no puedo entender por qué no puedo empujar a una matriz vacía newData .
No puede hacer async en forEach , por lo que necesita un bucle for simple y antiguo
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; }Esto debería funcionar
Hola, con respecto a su pregunta, aquí hay otra forma en que podría lograr lo que está buscando lograr. Avíseme si esto también lo ayuda en el futuro.
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 }En cuanto a por qué sucede esto: es un problema de tiempo.
Dado que comenzó el efecto secundario asíncrono en las subfunciones sin siquiera esperarlas en la función thunk principal, el thunk prácticamente terminó antes de que se resolvieran sus llamadas de fetch . Después de eso, está copiando esos datos en su tienda, y se congela, por lo que después de eso ya no se puede modificar.
=> espera en tu thunk hasta que todo el trabajo esté hecho.