Piotr Berebecki Piotr Berebecki - 6 months ago 23
Javascript Question

How to add another parallel AJAX call to the promises chain

I'm writing an app which


  1. makes an AJAX call to establish user location based on an IP
    address, then

  2. makes a second AJAX call to provide current weather data
    for this location, then

  3. shows this data in DOM



I've developed the following promises chain which successfully delivers the above:

getUserLocation()
.then(function(locationData) {
return getCurrentWeather(locationData);
}).then(function(currentWeatherData) {
return showCurrentWeather(currentWeatherData);
});


Now I need to add a further functionality to the app so that it:


  1. makes an AJAX call to establish user location based on an IP
    address, then

  2. makes a second AJAX call to provide current weather data
    for this location, and
    makes a third (concurrent, parallel) AJAX call to provide weather forecast data for this location, then

  3. shows the current weather data in DOM, and
    shows the weather forecast data in DOM



Below is what I've been experimenting with, but it does not work. Would you know how to fix this? My objective is to find a solution that makes only one AJAX call to get user location and then uses this data in two further AJAX calls (returned from the
getCurrentWeather
and
getWeatherForecast
functions).

getUserLocation()
.then(function(locationData) {
getCurrentWeather(locationData);
getWeatherForecast(locationData);
}).then(function() {
showCurrentWeather(currentWeatherData);
showWeatherForecast(weatherForecastData);
});


UPDATE 1 - WORKING SOLUTION FOUND:

Thanks to the approach suggested by @ReedSpool, I've managed to develop a working code:

getUserLocation()
.then(function(locationData) {
return jQuery.when(
getCurrentWeather(locationData),
getWeatherForecast(locationData)
);
}).then(function(currentWeatherData, weatherForecastData) {
showCurrentWeather(currentWeatherData[0]);
showWeatherForecast(weatherForecastData[0]);
});


The solution includes the
jQuery.when
. I also had to add index values of
0
to the arguments passed to the
showCurrentWeather
and
showWeatherForecast
functions. This is because the returned JSON now includes additional information about the
readyState
and
status
. This was not happening with my initial scenario with only one AJAX call to the weather API.

Answer

If you're indeed using jQuery promises (I'm gathering from the tags on your question, since the code provided has no jQuery specific stuff), then you're looking for jQuery.when() Every complete promise library has a similar function to this (Q.all for example)

Notice in your first example, you return the result of getCurrentWeather(locationData). Returning a promise inside a promise callback makes the outer promise wait for the inner promise to resolve. To wait for two or more promises to resolve, use jQuery.when() like...

getUserLocation()
  .then(function(locationData) {
    return jQuery.when(
      getCurrentWeather(locationData),
      getWeatherForecast(locationData)
    );
  }).then(function(curretnWeatherData, weatherForecastData) {
    showCurrentWeather(curretnWeatherData[0]);
    showWeatherForecast(weatherForecastData[0]);
  });

See the documentation here: https://api.jquery.com/jquery.when/

Comments