DEV Community

nexio-t
nexio-t

Posted on

Async/Await with JavaScript's Map Method: Using Promise.all

Introduction

This post will discuss using JavaScript's map method when dealing with async/await and promises. I'll be using a real-world example from my most recent project, viewable here.

Async/Await

To start, I first had to fetch data from The Covid Tracking Project's API, so I did it using async/await, like so:

  async function fetchTestingData() {

    const response = await axios.get(
      "https://covidtracking.com/api/v1/states/current.json"
    );

    return const data = response;

} 

The await keyword in the snippet above does what it describes: it forces the rest of the code to literally await the promise until it resolves. Async makes it so that the function always returns a promise.

Without an async/await, the data variable may come back undefined, since it may not fetch the response from the API before the return executes.

Combining the Map Method with Async/Await

The next step is to iterate over each state and attach coordinates, like so:

const addCoordinates = data.map(async state => {

    const coordinates = await axios.get(`https://exampleAPI.com/geocode/json?address=${state.stateName}`);

    state.coordinates = coordinates;

    return state 

  });

JavaScript's map method uses a callback to apply the function over each element of the array, which is fine. But recall that async functions always return a promise. As a result, you are returning an array of promises.

To summarize: the map method is a synchronous operation, but we are trying to do something asynchronous here, which combined with async/await leads to an array of promises instead of values.

Using Promise.all with an Asynchronous Map Method

The solution here is to use Promise.all, like so:

const addCoordinates = data.map(async state => {

    const coordinates = await axios.get(`https://exampleAPI.com/geocode/json?address=${state.stateName}`);

    state.coordinates = coordinates;

    return state 

  });

  const allStatesWithCoordinates = Promise.all(addCoordinates);

Promise.all is designed to take an array of promises as input and returns only one promise after all input promises have resolved, meaning the output will be one of values.

Top comments (2)

Collapse
 
saiyerniakhil profile image
Sai Yerni Akhil

Great article!
Can you please explain why does addCoordinates comes to be an array of promises, but not an array of objects/arrays?
When we do this for a single request, like in the first snippet it does return only the required data (not like any promise)

Collapse
 
fzaffarana profile image
Fabrizio Zaffarana

nice article.

I see the same problem than @saiyerniakhil .

You need to put your map code inside the promise.all. If you don't do this, you will execute the promises a line before.