0

Hi i have two JSON requests to make for a weather project, i need the data from the first request in order to personalise the second request for the user. My first request gets latitude and longitude of the user and the second needs those coordinates in the url for the current weather at that location.

 var arrLocat = [];//users suburb, city, country, lat and lon
 var userURL = "";//specific url tailored off users lat and lon
 var userWeather = [];//current weather at users lat and lon

  $(document).ready(function(){
  //first JSON request
    $.getJSON("http://ip-api.com/json", function (data){
     arrLocat = data;
      userURL = "http://api.openweathermap.org/data/2.5/weather?lat=" + arrLocat.lat + "&lon=" + arrLocat.lon + "&appid=61c4ebe6f40d2e2d7085e7c42d287e1d&units=metric";
       console.log(arrLocat);THIS RETURNS FIRST, WORKS FINE
  })
  //second JSON request
    .then(function(){
     $.getJSON(userURL).done(function(index){
      userWeather = index;
       console.log(userWeather);//THIS RETURNS LAST, WORKS FINE BUT SHOULD RETURN SECOND
    });
  })
  //do stuff here
    .then(function(){
     $("#locat").text(arrLocat.city + ", " + arrLocat.regionName + ", " + arrLocat.country);
      console.log(userWeather);//THIS RETURNS BLANK GLOBAL VALUE, NOT CARRYING VALUE FROM SECOND .THEN FUNCTION ALSO SHOULD RETURN LAST NOT SECOND
  })
});

I'm trying to run these in the order they are written, i understand that getJSON is asynchronous but i thought .then() was made to force order, to wait for the previous to complete before executing.

It took me a long while to figure out what was happening, it seems my final .then() is running before the second .then() JSON request. I'm new to deferred objects so i may be doing something fundamentally wrong that i'm not aware of?

Doodles
  • 37
  • 8

2 Answers2

0

First, don't use .done(), use .then() only. .done() is non-standard and has some odd behaviors. .then() is standard.

Second, when you have a second promise inside a .then(), you need to return it from the .then() handler in order to chain it properly.

Structurally, you want it to look like this:

$.getJSON(...).then(function(result1) {
    return $.getJSON(...)
}).then(function(result2) {
   // do stuff here
});

And, note that NO globals are needed here at all in order to get the final result into the last .then() handler. You may also find this useful:

How to chain and share prior results with Promises

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Thank you! I didn't know exactly what i was doing but the structure you provided helped significantly, i think i understand Promises a bit more now. – Doodles Feb 13 '17 at 01:52
-1

Chain them together by calling themselves inside each other, no need to use .then() which is part of a promise, not all API's implement that way...

var arrLocat = [];//users suburb, city, country, lat and lon
var userURL = "";//specific url tailored off users lat and lon
var userWeather = [];//current weather at users lat and lon

$(document).ready(function(){
//first JSON request
  $.getJSON("http://ip-api.com/json", function (data){
    arrLocat = data;
    userURL = "http://api.openweathermap.org/data/2.5/weather?lat=" + arrLocat.lat + "&lon=" + arrLocat.lon + "&appid=61c4ebe6f40d2e2d7085e7c42d287e1d&units=metric";
    console.log(arrLocat);
    $.getJSON(userURL).done(function(index){
      userWeather = index;
      console.log(userWeather);//THIS RETURNS LAST, WORKS FINE BUT SHOULD RETURN SECOND
      $("#locat").text(arrLocat.city + ", " + arrLocat.regionName + ", " + arrLocat.country);
      console.log(userWeather);//THIS RETURNS BLANK GLOBAL VALUE, NOT CARRYING VALUE FROM SECOND .THEN FUNCTION ALSO SHOULD RETURN LAST NOT SECOND
    });
  });
});
  • Promises are a much more powerful scheme for managing asynchronous operations than plain callbacks, particular when it comes to sequencing and propagating errors or coordinating multiple async operations. – jfriend00 Feb 12 '17 at 04:29
  • Thank you for helping, the code worked absolutely but doing it with Promises is a better learning experience for a newbie – Doodles Feb 13 '17 at 01:55