Martin
Martin

Reputation: 23

How to chain two ajax requests with promises

I am having trouble with ajax/promises. I have two ajax requests total, with the second ajax call relying data to be returned by the first ajax call.

My first ajax call finds Latitude, Longitude, and country code of the value of #search. My second ajax call finds the weather of that city, but the API URL is dependent on the Latitude, Longitude and country code that my first ajax call returns. So the second ajax call can't be started until the first one is finished.

My logic here is that var ajax1 is assigned a promise, and var ajax2 starts after ajax1.then() checks that ajax1's promise is resolved. Then ajax2 runs and returns another promise. Finally ajax2.done starts after it checks that ajax2's promise is resolved, and then starting my successWeatherFunction().

My problem is that ajax2.done is not working, as the console.log("test") is not showing up on the console. The two earlier console.logs, console.log(info) and console.log(weatherApiUrl) are working.

Thanks!

$("#search").keypress(function(event) {
if (event.which === 13) {
  var searchCity = $("#search").val();
  var jsonURL = "http://autocomplete.wunderground.com/aq?query=" + searchCity + "&cb=?"
  var ajax1 = $.getJSON(jsonURL);
  var ajax2 = ajax1.then(function(data) {
    var info = [];
    info.push(data["RESULTS"][0]["name"]);
    info.push(data["RESULTS"][0]["c"]);
    info.push(data["RESULTS"][0]["lat"]);
    info.push(data["RESULTS"][0]["lon"]);
    console.log(info);
    var searchLat = info[2];
    var searchLng = info[3];
    var countryCode = info[1];
    if (countryCode === "US") {
      var weatherApiUrl = "https://api.forecast.io/forecast/{APIKEY}/" + searchLat + "," + searchLng + "?exclude=minutely" + "&callback=?";
    } else {
      var weatherApiUrl = "https://api.forecast.io/forecast/{APIKEY}/" + searchLat + "," + searchLng + "?exclude=minutely" + "?units=si" + "&callback=?";
      console.log(weatherApiUrl);
    }
    return $.getJSON(weatherApiUrl);
  });
  ajax2.done(function(data){
    console.log("test");
    successCityWeather(data);
  });

Upvotes: 0

Views: 1905

Answers (3)

JAYBEkster
JAYBEkster

Reputation: 790

$.post(jsonURL)
    .then(function (data) {
        var info = [];
        // some actions
        return $.getJSON(weatherApiUrl);
    })
    .then(function(data, status, promise) {
        // some actions
        successCityWeather(data);
    })

Upvotes: 0

Radek Pech
Radek Pech

Reputation: 3098

If not sure, always use always() handler. That way you will know if the request actually finished with error or not at all.

$.ajax( ...params... )
      .always(function(jqXHR, textStatus) {
            if (textStatus != "success") {
                  alert("Error: " + jqXHR.statusText); //error is always called .statusText
            } else {
                  alert("Success: " + jqXHR.response); //might not always be named .response
            }});

Upvotes: 0

Magus
Magus

Reputation: 15104

Your code use then and done. done is the old promises jQuery syntax so you should use only then.

The following code works for me :

$(function() {
  $.get('/test').then(function() {
    console.log('First request end');
    return $.get('/test');
  }).then(function() {
    console.log('second request end');  
  });
});

But in your case, maybe a one of your request fail. Give a second parameter to then to log the error :

$.getJSON('...').then(function(data) {
    console.log('success', data);
}, function(data) {
    console.log('fail', data);
});

Upvotes: 1

Related Questions