How to sequence the .then() calls in a specific order?

Viewed 133

I am fairly new to the concept of promises, I am trying to build a simple pokemon list (aka pokedex). I am using the following code.

I want the names of the pokemons to be listed according to their indicies, I don't want the order to get disturbed. The code that I am using currently using doesn't guarantee this feature.

Inside the forEach() method the fetch() calls are not chained in any manner, so it depends on which response is received first, but I want the then() of index x to be executed before then() of index x+1.

const container = document.querySelector(".container");

fetch('https://pokeapi.co/api/v2/pokemon?limit=150')
  .then(response => response.json())
  .then(json => {
    json.results.forEach((el, index) => {
      fetch(el.url)
        .then(response => response.json())
        .then(json => {
          const pokemonName = el.name;
          const pokemontype = json.types[0].type.name;
          container.innerHTML += `(${index+1}) ${pokemonName} - ${pokemontype} <br>`;
        })
    })
  })
<div class="container"></div>

UPDATE: Below is my solution for the same using Promise.all()

const container = document.querySelector(".container");

fetch('https://pokeapi.co/api/v2/pokemon?limit=150')
  .then(response => response.json())
  .then(json => {
    const responseArr = [];
    json.results.forEach(el => {
      responseArr.push(fetch(el.url));
    });

    return Promise.all(responseArr);
  })
  .then(responses => {
    const jsonArr = [];
    responses.forEach(el => {
      jsonArr.push(el.json());
    });

    return Promise.all(jsonArr);
  })
  .then(jsons => {
    jsons.forEach((json, index) => {
      const pokemonName = json.name;
      const pokemonType = json.types[0].type.name;
      container.innerHTML += `(${index+1}) ${pokemonName} - ${pokemonType} <br>`;
    });
  })
<div class="container"></div>

1 Answers

You can use Promise.all and pass the result from the first API call, this will return the responses in the order as requested:

const container = document.querySelector(".container");

fetch('https://pokeapi.co/api/v2/pokemon?limit=150')
  .then(response => response.json(), e => {
    console.error(e);
    throw e;
  })
  .then(json => {
    Promise.all(json.results.map(el => fetch(el.url)))
      .then(arr => {
        arr.map(response => response.json())
          .forEach((result, index) => {
            result.then(el => {
              const pokemonName = el.name;
              const pokemontype = el.types[0].type.name;
              container.innerHTML += `(${index+1}) ${pokemonName} - ${pokemontype} <br>`;
            })
          })
      }).catch(e => {
        console.error(e)
        throw e;
      });
  }).catch(e => {
    console.error(e)
    throw e;
  });
<div class="container"></div>

Related