0

I am trying to use the new async/await in conjunction with mapping over an array of values. However I am a bit confused, which should have the await keyword infront of it, in this specific scenario.

There isnt much information regarding this topic yet.

I am trying to simply map() over and array of values, which are used in an Axios get() request, which then returns a then() value, which gets added to the array returned by the map() function.

This is my code right now:

async function get_prices (arrayOfDates, crypto, FIAT) {
  // I tried this way (return value can be found below)
  let arry_of_prices = arrayOfDates.map(async function(date){
    let a = await fetch_data(date, crypto, FIAT)
    return a
  });

  // And this way (return value can be found below)
  let arry_of_prices = await arrayOfDates.map(date => fetch_data(date, crypto, FIAT));
} 

const fetch_data = (timestamp, crypto, FIAT) => {
  axios.get(`https://min-api.cryptocompare.com/data/pricehistorical?fsym=${crypto}&tsyms=${FIAT}&ts=${timestamp}`)
  .then(function (response) {
    return Object.values(response.data).map(key => Object.values(key))[0][0]
  })
  .catch(function (error) {
    console.log(error);
  });
}

let arr = [1468965600, 1469052000, 1469138400,1469484000]

get_prices(arr, "BTC", "USD").then(arr => console.log(arr))

The first try returned 4 resolved promises, but the values were undefined. Whereas the second return an array with 4 undefined.

Does anyone have an idea of how this could be structured, so that the map() waits until the function is resolved and then adds the value to the array?

1 Answer 1

1

map doesn't know anything about promises, so when you use an async callback with map, you'll get an array of promises, not values. If you then want a promise that will resolve when all of those promises have resolved, you can use Promise.all.

However, in your case, you don't need an async function, since you're using fetch_data in the callback. You need to modify fetch_data so it returns the promise from axios.get (and remove the catch handler):

const fetch_data = (timestamp, crypto, FIAT) => {
  return axios.get(`https://min-api.cryptocompare.com/data/pricehistorical?fsym=${crypto}&tsyms=${FIAT}&ts=${timestamp}`)
  .then(function (response) {
    return Object.values(response.data).map(key => Object.values(key))[0][0]
  });
}

(This is one of the rules of promises: If you're returning the promise, you don't handle rejections from it [unless you want to convert them into different rejections, or if you can usefully convert them to resolutions instead]. If you don't return the promise, you do handle rejections.)

Now you already have a promise, so you use that in the map (no need for async):

async function get_prices (arrayOfDates, crypto, FIAT) {
  let arr_of_price_promises = arrayOfDates.map(function(date){
    let a = fetch_data(date, crypto, FIAT)
    return a
  });
  return Promise.all(arr_of_price_promises);
}

Notice I removed the await from in front of fetch_data. We return fetch_data's promise directly, then wait for them all.

Or with an arrow function:

async function get_prices (arrayOfDates, crypto, FIAT) {
  let arr_of_price_promises = arrayOfDates.map(date => fetch_data(date, crypto, FIAT));
  return Promise.all(arr_of_price_promises);
}
Sign up to request clarification or add additional context in comments.

5 Comments

But doesnt this still return a resolved promise, with undefined value?
@Jousi: No, it returns a promise that will resolve when all the fetch promises resolve (or reject when the first fetch promise rejects). It resolves with an array which is the resolved values of each of the fetch promises, in the order in which those promises were given to Promise.all.
@Jousi: Oh, sorry, you're using your own fetch_data, not fetch. You need to modify fetch_data a bit, I'll add that.
Yep just noticed it too, adjusted :) Thanks TJ!
@Jousi: :-) Updated the answer to show what to do to fetch_data. Glad that helped!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.