Using return data from an async function, in another function

I’m doing a little data analysis from chess.com data

I have this code

const getUsernames = async function() {
  let response = await chessAPI.getCountryPlayers('RE')
  names = [...response.body.players]
  //console.log(names)
  return names
}

const grabPlayerScores = async function() {
  let players = getUsernames()
  // let playerStats = [];
  for (i = 0; i = players.length; i++) {
    let data = await chessAPI.getPlayerStats(i)
    console.log(data)
  }
}

grabPlayerScores();

I can’t get the other function to await the return of the first. I know I should use promises or structure my other function differently but I’m still getting the hang of these types of functions.

Answer

As a best practice, you should make sure all of your functions return a value. Use const for variables that will not change, and let for variables that you absolutely will change. Watch out for name = ... where you didn’t write const or let, as this makes names into a global –

const getUsernames = async function() {
  const response = await chessAPI.getCountryPlayers('RE')
  return response.body.players // <- probably no need to copy
}
const grabPlayerScores = async function() {
  const players = await getUsernames()
  return Promise.all(players.map(p => chessAPI.getPlayerStats(p)))
}

Now grabPlayerScores will be a promise containing an array of all player scores –

grabPlayerScores().then(console.log).catch(console.error)
[ ..., ... ,... ]

Maybe you want the player data combined with the score data in the final output?

const grabPlayerScores = async function() {
  const players = await getUsernames()
  return Promise.all(players.map(async p => ({
    player: p,
    scores: await chessAPI.getPlayerStats(p)
  })))
}
grabPlayerScores().then(console.log).catch(console.error)
[ { player: "alice", scores: ... },
  { player: "brenda", scores: ... },
  { player: "catherine", scores: ... } ]

Another good practice is to make your functions take parameters. This makes them more reusable in other areas of your program –

const getUsernames = async function(countryCode) {
  const response = await chessAPI.getCountryPlayers(countryCode)
  return response.body.players
}

const grabPlayerScores = async function(countryCode) {
  const players = await getUsernames(countryCode)
  return Promise.all(players.map(async p => ({
    player: p,
    scores: await chessAPI.getPlayerStats(p)
  })))
}

Now you pass "RE" as an argument to your function, allowing you to easily reuse this function for other countries –

grabPlayerScores("RE").then(console.log).catch(console.error)