Wellington Perez
Wellington Perez

Reputation: 33

Promise.all() to await the return of an object property

Inside an async function i have a loop and inside this loop i need to use await to resolve a promise from another async function.

async function smallestCities(states) {
  const citiesInState = [];
  for (const state of states) {
    const length = await lengthOfState(state.Sigla);
    const stateObject = {
      state: state.Sigla,
      cities: length,
    };
    citiesInState.push(stateObject);
  }

  citiesInState.sort((a, b) => {
    if (a.cities > b.cities) return 1;
    if (a.cities < b.cities) return -1;
    return 0;
  });
  return citiesInState.filter((_, index) => index < 5).reverse();
}

It's work fine, but eslint says to disallow await inside of loops and use Promise.all() to resolve all promises.

The problem is that my promises are in an object property:

return of the function

How can i figure out to use Promise.all() with properties of an object?

Upvotes: 3

Views: 2006

Answers (2)

Anssi Herranen
Anssi Herranen

Reputation: 569

const NEW_LAND = 'newLand'
const ACTUAL_FINLAND = 'actualFinland'
const PIRKKAS_LAND = 'pirkkasLand'

const STATE_CITY_MAP = {
  [NEW_LAND]: ['HELSINKI', 'VANTAA', 'KORSO'],
  [ACTUAL_FINLAND]: ['TURKU'],
  [PIRKKAS_LAND]: ['WHITE RAPIDS', 'NOKIA'],
}

const mockGetCities = (stateName) => new Promise((res) => {
  setTimeout(() => { res([stateName, STATE_CITY_MAP[stateName]]) }, 0)
})

const compareStatesByCityQty = (a, b) => {
  if (a[1].length > b[1].length) return 1
  if (a[1].length < b[1].length) return -1
  return 0
}

const getSmallestStates = async (stateNames, cityQty) => {
  const cities = await Promise.all(stateNames.map(mockGetCities))
  return cities
    .sort(compareStatesByCityQty)
    .reverse()
    .slice(0, cityQty)
}

;(async () => {
  const stateNames = [NEW_LAND, ACTUAL_FINLAND, PIRKKAS_LAND]
  const smallestStates = await getSmallestStates(stateNames, 2)
  console.log(smallestStates)
})()

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 370709

Chain a .then onto the lengthOfState call to make the whole Promise resolve to the object you need, inside the Promise.all:

const citiesInState = await Promise.all(
  states.map(
    state => lengthOfState(state.Sigla).then(cities => ({ state: state.Sigla, cities }))
  )
);

Upvotes: 8

Related Questions