0

I have an array of ids, stored in ids, that I'm mapping over an async function, asyncFunc. I want to store the result of the mapping into newArr and then update state via setState. Here's my code:

useEffect(() => {
    const newArr = [];
    ids.map((element) => {
      asyncFunc(variables).then((data) => {
        newArr.push({ layer: makeLayer(data) });
      });
    });
    setState([...layers, ...newArr]);
  }, [variables]);

My issue is that the state is updating before the mapping completes. How can I use .then() to update the state only when data from all the mappings were returned? Wrapping ids.map with Promise.all didn't work. In addition, the following returns an error:

useEffect(() => {
    const newArr = [];
    (ids.map((element) => {
      asyncFunc(variables).then((data) => {
        newArr.push({ layer: makeLayer(data) });
      });
    })).then(()=> {
       setState([...layers, ...newArr]);    
    })
  }, [variables]);
mmz
  • 1,011
  • 1
  • 8
  • 21
  • What about using `Promise.all`? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all – evolutionxbox Apr 21 '22 at 14:12
  • 2
    Does this answer your question? [Using promise function inside Javascript Array map](https://stackoverflow.com/questions/39452083/using-promise-function-inside-javascript-array-map) – Emile Bergeron Apr 21 '22 at 14:14
  • 1
    Wrapping the map into Promise.all would have probably worked if your map did actually return anything, you are missing return statement inside map – Samuel Olekšák Apr 21 '22 at 14:15
  • 2
    @evolutionxbox he said he tried it already—but I would be interested to see a snippet of how you tried it. – saylestyler Apr 21 '22 at 14:15

1 Answers1

4

Declare a async function to populate the array and return your array within a Promise.all. Something like this should work for what you're trying to accomplish:

useEffect(() => {
    const populateArray = async () => {
      const newArr = await Promise.all(ids.map(async element => {
        const data = await asyncFunc(variables)

        return { layer: makeLayer(data) }
      })

      setState([...layers, ...newArr]);
    }

    populateArray()
  }, [variables]);
Alex K
  • 832
  • 4
  • 8