Home > Mobile >  return undefined on fetch request inside map react
return undefined on fetch request inside map react

Time:03-26

I tried to get a map array from fetch resolves so on every element inside favoriteCards it returns a value and assigns it in test

useEffect(() => {
  const test = favoriteCards.map((card) => {
    accuWeatherApi.getCurrentWeather(card.key).then((res) => {
      return res;
    });
  });
  setRenderFavorites(test);
}, [favoriteCards]);

console.log(renderFavorites)

I always get undefined no matter what I do

CodePudding user response:

The getCurrentWeather operation is asynchronous. So in this case you need to await a series of operations to get their results before you can set those results to a state value.

In a useEffect that might look something like this:

useEffect(() => {
  const fetchWeather = async () => {
    // begin the asynchronous operations
    const promises = favoriteCards.map(card => accuWeatherApi.getCurrentWeather(card.key));

    // wait for all of them to complete
    const results = await Promise.all(promises);

    // update state with the results
    setRenderFavorites(results);
  }

  fetchWeather();
}, [favoriteCards]);

Though as you might imagine, there are a variety of ways to do this. For example, the above code performs all of the asynchronous operations right away and the results will be in whatever order they finish. If you need them to be in the same order, you might await each operation one at a time. For example:

useEffect(() => {
  const fetchWeather = async () => {
    const results = [];

    // await each operations in order
    for (const card of favoriteCards) {
      results.push(await accuWeatherApi.getCurrentWeather(card.key));
    }

    // update state with the results
    setRenderFavorites(results);
  }

  fetchWeather();
}, [favoriteCards]);

Note that in each case the function passed to useEffect itself is not async. But since asynchronous operations need to be awaited, internally that function defines a function which is async and then invokes that function. Internal to that function is where you'd await the operations.


As an aside, it's also worth pointing out that there was a second issue in your code... The syntax of your use of .map() explicitly doesn't return anything. When curly braces are used in the function passed to .map() then there is no default return and you need to explicitly return a value. So even if you were awaiting the operations or if they weren't asynchronous in the first place, it would still be undefined because there's no return value.

  • Related