AJAX/JSON and callbacks

This is a long post. The TL/DR version: I sort of understand callbacks. And I’ve made successful AJAX calls in the past. I’m just strangely stumped by, um, exactly what code do I put where to use the results effectively?


I feel bad asking for the level of hand-holding that I’m about to, but I’ve been stalled on the Weather App for SIX WEEKS!!! The issue is my basic understanding of callbacks, and how to write an ajax (or just $.getJSON) request in such a way that its response is usable outside the call.

Lemme break it down to the very beginning.
As I see it, there are three steps here:

  1. Find user’s location (ultimately, I’d prefer to go with the https and geolocation solution instead of IP). Presumably, set some kind of var location or the like to the response.
  2. Use that location value in a call to a weather API.
  3. Use the weather conditions returned in a call to some graphics library API (or perhaps just hotlink to the limited number of possibilities).

After initial trouble with geolocation, and turning to IP (I see now that I can simply slap https into the URL bar to overcome that, and will probably go back to it) I was at this point: http://codepen.io/AbdiViklas/pen/BKEaYz?editors=1010

Obviously, though I can get a result from the IP location call, and put it into the DOM within that call, I can’t use it outside the call—like, say, in my next call to a weather API. I suppose I could nest the weather call inside the location call, but that idea… scares me. Where would it end?

Clearly, the problem is one of scope, and the solution seems to be callbacks. (Yes, I know that there are newer solutions like promises and let, and I very much want to learn about them, but I wanted to know about the “old way” first, to appreciate just what the “new ways” are trying to improve upon.) I read about half a dozen pages about callbacks, and just yesterday I proved to myself that I can actually use callbacks to make something happen: https://codepen.io/AbdiViklas/pen/YWWLaP?editors=1011

I’m still having trouble, though, figuring out how to work that functionality into an AJAX call. Where do I, um, put the callback function? and the function that calls it? Is it like this? http://codepen.io/AbdiViklas/pen/RRRyZN?editors=1010
… clearly not; something’s very wrong there. I’ve gotten things to work before using $.getJSON instead of $.ajax; I know in that context you just “put the callback after the URL”—like this?
http://codepen.io/AbdiViklas/pen/XKKPxy?editors=1010
… sigh, I guess not like that.

This seems like such a basic issue—make calls to more than one API, use the responses usefully in other calls—that I would have thought I could figure it out on my own. But dude, SIX WEEKS. I can feel myself seriously losing traction and momentum, and I want to get a move on.

Can you not store the location values returned by the IP lookup in variables declared in a “common to both” scope and then either pass those variables in as arguments to the second function, or just use them directly?

(function() {
“use strict”;
var long = 0;
var lat = 0;

function getLocation() {
    var locationData = code to find coordinates by IP...
        long = locationData.long;
        lat = locationData.lat;
}

function getWeather() {
    var url = 'http://api.openweathermap.org/data/2.5/weather?lat=' + lat + 
                        '&lon=' + long + whatever else you need...
}

})();

Hello !

I get that this can get difficult, but you were quite close to findind the correct way to do this. I stopped using Geolocation because it didn’t work anymore in Chrome with http.

I then switched to ip-api just like you did in that last codepen to retrieve the latitude and longitude, and would use theses two values for a call to OpenWeather.

function getLocation() { 
  var latitude,
      longitude;
  $.getJSON("http://ip-api.com/json/", function(data) {
    latitude = data.latitude;
    longitude = data.longitude;
  });
  
  getWeather(latitude, longitude);
}

function getWeather(lat, lon) {
  // call to OpenWeather with theses two arguments !
}

getLocation();

The way I would do this is two functions, say getLocation and getWeather.

getLocation is you call to ip-api using .getJSON. you need to store 2 variables using the data it returns. to see this data first, console.log it out ! You can then correctly points to what you need, in this case it’s data.latitude and data.longitude.

Right after this, and still within that function, you can call getWeather using theses two variables as arguments. getWeather is another .getJSON call that will pass theses two arguments in it’s query. You’ll then be able to retrieve informations based on your location !

Hope that makes sense :slight_smile:

1 Like

Thanks Mizu! That got me a long way. Now there’s still some problem. Here’s where things currently stand:

The location works; the weather doesn’t. But the weather call, extracted from its function, works:
https://codepen.io/AbdiViklas/pen/zBKONg?editors=1010

Is there a problem with the fact that the execution of getWeather is in a different scope than its declaration? a problem with the conditions variable, maybe?

You should put the getWeather function inside your sucess function, right after you define lat and lon !

1 Like

I also forgot to tell you that if your api call is secured (HTTPS) you need to be secured on the calling side too. You just have to put https before codepen url !