0

I am using an API to retrieve data (of several airports), based on their airport codes...

async function airpt(codes){
    const airportCredential = {
      "method": "GET",
      "headers": {
        "x-rapidapi-host": "airport-info.p.rapidapi.com",
        "x-rapidapi-key": "xxxx"
      }
    }

    return Promise.all(
      codes
      .map(code =>
        fetch("https://airport-info.p.rapidapi.com/airport?iata="+code,airportCredential)
        .then(r => r.json())
      )
    );

  }

A call like airpt(['JFK','LAX'] yields an array with results like so:

 Array(2)
0: {id: 3406, iata: 'JFK', icao: 'KJFK', name: 'John F. Kennedy International Airport', location: 'New York City, New York, United States', …}
1: {id: 4044, iata: 'LAX', icao: 'KLAX', name: 'Los Angeles International Airport', location: 'Los Angeles, California, United States', …}
length: 2

That's working fine. But how would I return a (single) promise from this function with all the data packaged into an object, which uses the input codes as keys?

I know how to transform the array into an object:

array.reduce((obj, item) => {
    return {
      ...obj,
      [item['iata']]: item,
    };
  }, {});

I know how to do that, using .then(...) after Promise.all() has been resolved. However, I would like to have the repackaging into an object as part of the async function.

  • `airpt` returns a promise. You will either need to await it before using `reduce` or put the `reduce` inside a following `then`. – evolutionxbox Nov 21 '21 at 15:07
  • 1
    Does this answer your question? [How to return the response from an asynchronous call](https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – evolutionxbox Nov 21 '21 at 15:07
  • "*I know how to do that using `.then(...)`, however I would like to do it as part of the async function.*" - so just use `await` instead of `.then(…)`? – Bergi Nov 21 '21 at 15:12
  • @evolutionxbox ... Thanks for the quick reaction. I believe I understand the basics of `async/await` and `then`... However I didn't find a good way to return an Promise object from `airpt`. – Dirk Albrecht Nov 21 '21 at 15:13
  • You can do `return Promise.all(...).then(array => array.reduce(...))` – derpirscher Nov 21 '21 at 15:27
  • "*I didn't find a good way to return an Promise object from `airpt`*" - since `airpt` is an `async function`, it [always returns a promise](https://stackoverflow.com/q/43422932/1048572). – Bergi Nov 21 '21 at 15:33
  • Or you can do `return (await Promise.all(...)).reduce(...)` – derpirscher Nov 21 '21 at 15:35

1 Answers1

0

You seem to already have the pieces you need, so hopefully you just need to see them put together. Here's what it looks like to execute some extra code after the promise.all, and return an object based on the array:

async function airpt(codes){
  const airportCredential = {
    "method": "GET",
    "headers": {
      "x-rapidapi-host": "airport-info.p.rapidapi.com",
      "x-rapidapi-key": "xxxx"
    }
  }

  const array = await Promise.all(
    codes
    .map(code =>
      fetch("https://airport-info.p.rapidapi.com/airport?iata="+code,airportCredential)
      .then(r => r.json())
    )
  );

  return array.reduce((obj, item) => {
    return {
      ...obj,
      [item['iata']]: item,
    };
  }, {});
}
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • Thanks, that cuts it! Just like @derpirscher 's suggestion of `return Promise.all(...).then(array => array.reduce(...))` – Dirk Albrecht Nov 22 '21 at 12:29