Problem with loop fetching and returing response

64 views Asked by At

It's my first stackoverflow querstion so be gentle for me

I'am making pokedex app with react query and fetch but I have problem with returning array of my pokemons.

I'm trying to fetch a pokeApi which returns an array of results consisting of objects with another url. Then I try to map trough results array and fetch url for individual pokemon then push it to the arr variable. In the end, I'am returning arr which is not readable.

How to properly push data to arr in map?

What i'am doing wrong? Is there solution?


const fetchData = async (key) => {
    const data = await fetch(`https://pokeapi.co/api/v2/pokemon`)
      .then((res) => res.json())
      .then((data) => {
        return data;
      });
    const arr = [];
    data.results.map((item) => {
      return fetch(item.url)
        .then((res) => res.json())
        .then((data) => {
          arr.push(data);
        });
    });
    return arr;
  };

  const { isLoading, data } = useQuery("pokemons", fetchData, {
    refetchOnWindowFocus: false
  });

  if (isLoading) return <div>loading...</div>;
  console.log(data); // cant read
  return <div>Data loaded</div>;

https://codesandbox.io/s/strange-pond-wz4ws?fontsize=14&hidenavigation=1&theme=dark

2

There are 2 answers

2
JAM On BEST ANSWER

The issue with your fetchData function, is that it does not wait for any of the subsequent fetches for each item.

To solve this, you have to map each of the results as a Promise, then wait for all these promises to finish by utilizing Promise.all

Your fetchData function might look something like this:

  const fetchData = async (key) => {
    const data = await fetch(`https://pokeapi.co/api/v2/pokemon`)
      .then((res) => res.json())
      .then((data) => {
        return data;
      });

    // Wait for all subsequent fetches to finish
    const arr = await Promise.all(
      data.results.map((item) => fetch(item.url).then((res) => res.json()))
    );

    return arr;
  };
0
trixn On

The solution proposed by @JAM but without any .then(). Error handling is omitted (You can use catch() or a try/except block):

const fetchData = async key => {
    const res = await fetch(`https://pokeapi.co/api/v2/pokemon`);
    const data = res.json();

    // Wait for all subsequent fetches to finish
    return Promise.all(
        data.results.map(async item => {
            const res = await fetch(item.url);
            return res.json();
        }
    );
};