0

I have a loop with about 15 items and need to make two api calls each time the loop is iterated through. So I need to make the API request within the loop and then do some simple calculation before the loop moves on.

Assume I have a function called getFlightData that takes 3 parameters - a departing city, arriving city, and the date. The function needs to make an API request and then return the JSON from the API call.

See my code below.

const airportsList = [
    "SFO",
    "SEA",
    "JFK",
    "YTZ"
 ]

   for (var i = 0; i < airportsList.length; i++) {
     // loop through the airports

     var departingFlightCost, returningFlightCost;
     getFlightData("MEX", airportsList[i], date1);
     getFlightData(airportsList[i],"MEX", date2);
   }


 function getFlightData(departingCity, arrivingCity, date) {
    var options = {
      method: 'GET',
      url: 'https://apidojo-kayak-v1.p.rapidapi.com/flights/create-session',
      qs: {
        origin1: departingCity,
        destination1: arrivingCity,
        departdate1: date, //'2019-12-20',
        cabin: 'e',
        currency: 'USD',
        adults: '1',
        bags: '0'
      },
      headers: {
        'x-rapidapi-host': 'apidojo-kayak-v1.p.rapidapi.com',
        'x-rapidapi-key': API_KEY
      }
    };
    request(options, function (error, response, body) {
      const flightData = body;
    });
  }

Each time the loop iterates through a city, I need to get the contents of the two API requests and then do a simple calculation before moving on. How do I most effectively do this in node?

6
  • If getFlightData() is an asynchronous (networking) operation, you will have to show us that code because it will need to be modified too. Commented Aug 23, 2019 at 2:35
  • @jfriend00 I updated it accordingly Commented Aug 23, 2019 at 2:42
  • Start by reading this How do I return the response from an asynchronous call. That will help you understand how to fix getFlightData(). That has to be fixed first (ideally to return a promise) and then you can work on your loop. Commented Aug 23, 2019 at 2:54
  • Can you provide an example of how to fix this @jfriend00 Commented Aug 23, 2019 at 2:57
  • Well, I'm trying to help you learn how to fix this yourself rather than just write a bunch of code for you. Did you read the link I gave you. Does it give you ideas how to fix getFlightData()? Commented Aug 23, 2019 at 3:21

1 Answer 1

1

You can try this:

const getFlightData = (departingCity, arrivingCity, date) => new Promise((resolve, reject) => {
  const options = {};

  request(options, (error, res) => {
    if (error) {
      return reject(error);
    }

    return resolve(res);
  });
});

const airportsList = [
  "SFO",
  "SEA",
  "JFK",
  "YTZ"
];

// things will run in parallel
for (let i = 0; i < airportsList.length; i++) {
  const date1 = new Date();
  const date2 = new Date();

  const tasks = [
    getFlightData("MEX", airportsList[i], date1),
    getFlightData(airportsList[i], "MEX", date2)
  ];

  // wait 2 tasks completed and handle
  Promise.all(tasks)
    .then(responses => {
      const res1 = responses[0];
      const res2 = responses[1];

      // continue doing something here
    })
    .catch(error => {
      // handle error here
    })
}

Or if you want everything runs step by step, you can replace for loop with this function:

const syncLoop = i => {
  const date1 = new Date();
  const date2 = new Date();

  const tasks = [
    getFlightData("MEX", airportsList[i], date1),
    getFlightData(airportsList[i], "MEX", date2)
  ];

  // wait 2 tasks completed and handle
  Promise.all(tasks)
    .then(responses => {
      const res1 = responses[0];
      const res2 = responses[1];

      // continue doing something here

      // schedule a new function
      syncLoop(i + 1);
    })
    .catch(error => {
      // handle error here
    })
};

syncLoop(0);

If you need to do something after all of async tasks were done:

const allTasks = [];
// things will run in parallel
for (let i = 0; i < airportsList.length; i++) {
  const date1 = new Date();
  const date2 = new Date();

  const tasks = [
    getFlightData("MEX", airportsList[i], date1),
    getFlightData(airportsList[i], "MEX", date2)
  ];

  // wait 2 tasks completed and handle
  allTasks.push(Promise.all(tasks)
    .then(responses => {
      const res1 = responses[0];
      const res2 = responses[1];

      // continue doing something here

      // remember to return something here
      // things will appear in the below Promise.all
      return res1;
    })
    .catch(error => {
      // handle error here
    })
  );
}

Promise.all(allTasks)
  .then(allResponses => {
    // do something when all of async tasks above were done
  })
  .catch(error => {
    // handle error here
  });
Sign up to request clarification or add additional context in comments.

2 Comments

Super helpful, thank you!! How can I output the final result though, once the loop has completed? I need to send this back as the endpoint's response data
hey, I've just update example code, please check if it fits your need

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.