Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Promise only resolves correctly on page refresh

I am playing around with an API that gets a list of Pokemon and corresponding data that looks like this.

export function SomePage() {
const [arr, setArray] = useState([]);

   useEffect(() => {
    fetchSomePokemon();
  }, []);


  function fetchSomePokemon() {
    fetch('https://pokeapi.co/api/v2/pokemon?limit=5')
     .then(response => response.json())
     .then((pokemonList) => {
       const someArray = [];
     pokemonList.results.map(async (pokemon: { url: string; }) => {
       someArray.push(await fetchData(pokemon))
     })
     setArray([...arr, someArray]);
    })
   }

   async function fetchData(pokemon: { url: string; }) {
    let url = pokemon.url
     return await fetch(url).then(async res => await res.json())
    }

    console.log(arr);

  return (
      <div>
      {arr[0]?.map((pokemon, index) => (
          <div
            key={index}
          >
            {pokemon.name}
          </div>
        ))
      }
      </div>
  );
}

The code works(kind of) however on the first render the map will display nothing even though the console.log outputs data. Only once the page has been refreshed will the correct data display. I have a feeling it’s something to do with not handling promises correctly. Perhaps someone could help me out.
TIA

Expected output: Data populated on initial render(in this case, pokemon names will display)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The in-build map method on arrays in synchronous in nature. In fetchSomePokemon you need to return a promise from map callback function since you’re writing async code in it.

Now items in array returned by pokemonList.results.map are promises. You need to use Promise.all on pokemonList.results.map and await it.

await Promise.all(pokemonList.results.map(async (pokemon: { url: string; }) => {
       return fetchData.then(someArray.push(pokemon))
     }));
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading