Stuck on Weather app for two weeks, can't figure out what's wrong

I haven’t been able to get my JSON data back from the API and I have been stuck for weeks. No one’s been able to offer a solid piece of advice on what to do and I don’t feel any closer to completing it. Can someone take a look at my CodePen and see if they can guide me through getting the JSON data from the API? Since Codepen went to HTTPS and there were some issues with the OpenWeather API, I switched to Darksky if that makes a difference. The URL that it outputs works and I can see data, but just can’t seem to get it into my code.

Thanks for the help in advance!

So, it looks like you’ve got a couple of issues going on.

The first problem is with your getGeolocation function. And actually, that’s two problems kind of rolled up together into one.

First, you’re never actually returning a value. When you console.log() the weatherURL, you’re printing it out so that you can read it… but the rest of your program can’t. If you want to assign the URL to a variable (like you’re doing in line 26), then you need to use the return statement. Like this:

console.log(weatherURL) // prints value
return weatherURL // passes value to, eg, a variable

With me so far?

Yes, I follow so far!

Great. Then this next part gets a bit tricky. It turns out that the getGeolocation function takes time to run… When you first call that function, it will check to see if the navigator.geolocation functionality exists, and then - assuming it does - it will ask the browser to try to get the user’s position.

And then - while you program is waiting for the browser to respond - it will go ahead and try to get a head start on whatever step comes next.

If you go down to your

$(".testButton").on('click'....

function, what will happen is something like this:

  1. Go ahead and call the getGeolocation function.
  2. Get the value of weatherURL (which doesn’t exist yet)
  3. Send off the JSON request using the current value of weatherURL (which, again, hasn’t been set yet)

And then, some time after all this, the browser will get back to you with the actual location.

But it’s already too late.

Okay, so it sounds like I need to delay the getJSON function from running for a few seconds? Is that what I’m missing? If that’s the only thing wrong I’m sure there’s a way to do that in jQuery right?

There are a couple of ways that we can solve this problem. The first one - and probably the simplest - is to use callback functions. I would try doing something like this:

  1. Change your getGelocation function to call a function, instead of returning a value
function getGeolocation(callback) {
  // your code here
  return callback(weatherURL) // instead of the return statement
}
  1. Rewrite some of the button-click code, so that you have a function you can pass into the getGeolocation function:
// a function to get the weather info
function getWeather(url) {
  return $.getJSON(url, function(data) {
    console.log(data);
  }
}

// call that function from inside your click handler
$(".testButton").on("click", function() {
  getGeolocation(getWeather);
});
1 Like

This might be where I get confused. A callback function is essentially just a function within a function, right? So would I just move my click event function to the end of the getGeolocation function?

Yeah - sorry, I had to step away from the computer for a second. I went back and made some edits… does that help any?

Yes, it helps, but to be completely honest I’m still a little lost as to how to do this. You’ve helped more than anyone else has been able to! I appreciate it immensely!

function getGeolocation() {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      var latitude = position.coords.latitude;
      var longitude = position.coords.longitude;
      var weatherURL = "https://api.darksky.net/forecast/247ae71ddd50cb8c50d9ce68a0318b53/" + latitude + "," + longitude;
      console.log(weatherURL);
      callback(weatherURL) {
         $(".testButton").on("click", function() {
              $.getJSON(weatherURL,function(data) {
              console.log(data.length);
         });
};
    },
    function(error){
      handleGeolocationErrors(error);
    });
  } else {
    console.log("Browser does not support geolocation services.");
    return false;
  }
}

I’m trying to think whether I know of any good tutorials on callbacks…

In any case, the “trick” is learning to think of functions as just another type of variable. You can pass a number or a string into a function. You can also pass functions into functions, and then call them from within functions. That’s basically what you’re doing here: Instead of creating a “getGeolocation” function that returns a URL, you’re creating a function that gets a URL, and then calls a function with that URL as a parameter.

Play around with the idea a little bit.


Anyway - your program logic works now on codepen, right? If you open up the console - your browser’s console, not codepen’s - you can see that the API request is being made?

This explanation looks really good - might be worth taking a look and seeing if it helps things “click”:

That is a super helpful explanation actually! I think my logic just gets confused sometimes with functions and the input on functions. I’m going to try and rewrite this with my newfound knowledge of callbacks. Additionally I can’t thank you enough for all your help. If it’s okay, I might come back here if I remain stuck on this problem by the end of the day.

Again, thank you a million times over.

Just want to say that the responses by @AgathaLynn demonstrate a true skill and nuance for teaching, which is especially hard in a forum setting like this. Well done.