Weather App: Celsius to Fahrenheit Weirdness

I’m having some trouble getting the temperature to convert correctly with my weather app. I seem to be able to get from F to C without any problem, but I can’t convert from C back to F. And now for some reason, I can’t seem to get my button to all now, which is probably the result of all the testing/debugging I’ve been doing.

Any ideas? Here’s my pen: https://codepen.io/Qwicksilver/pen/kkZBrj?editors=1010

Your button stopped working because you commented out your click handler starting at about line 196. You’ll want to scrap that whole handler and try something else. I think the easiest way to change scales is to precompute them right after the weather data has arrived, then change out the content of your temperature elements when you click the button.

The rest of your app looks great, but there are a couple of things I noticed that merit comments:

  • You don’t need the CORS proxy (https://cors-anywhere.herokuapp.com/) because you’re using a secure weather service and we’re connecting to the pen via HTTPS. Everything will work.

  • It’s cool that you’re doing the 5 day forecast, but everything from line 36 to 91 is unnecessarily repeated code. It’s possible to do this sort of thing with a loop, but you may have to change the ids you use in your markup. Another project for another time, but it’s totally within your grasp to do.

Line 196 is actually the old code I was using as a reference from a previous weather app I created. It was easier to have it commented out in my current code than to have to switch between tabs all the time on my laptop. The code I’m having trouble with for my button is on lines 110 - 130.

The CORS proxy: I was told by several people in the chat that I needed the CORS proxy for Chrome since it won’t work any other way. It does work fine in Firefox, but my version of Chrome (the most updated version) won’t work without the CORS proxy. So I’m keeping it there for now so others can view the site when I share the link.

The 5 day forecast: I’m using Moment.js to have the dates show up correctly on my app. I’m not sure the best way to have this work with a loop, so this is why the app is set up from lines 36 to 91. If you have a way to have Moment.js work correctly while using a loop, I would love to see how to set this up. I’ve tried this myself with no luck which is why I have it set up as it is now.

Oh, sure enough! I just tried it in Chrome and it refused the data. Normally CORS proxies are needed because of the browser’s same-origin policy (it will reject executable code from anywhere but the server it came from). In this case, DarkSky has disabled CORS from the server by not including an important header. Turns out, they don’t actually want people using an API key in client side JavaScript. I guess a CORS proxy is our little way of sticking it to “The Man”!

You’ve got a for loop defined on line 96. The reason your button isn’t working right now is because you’re defining both tempState and #convertTemp’s click handler on each iteration of this loop. In order for this to work, both of these need to be defined outside of the loop. I placed tempState towards the top and the handler just before the loop’s definition and I was able to convert the current day’s temperature. Getting that to change all of the temperatures will take a bit of finagling. However, let’s talk about that loop for a second.

What’s interesting is that you’re quite close to getting this set up yourself. It looks like you had an idea to do it yourself, but didn’t. You’ve got that loop on line 96, but inside the loop you’ve hard-coded all of the array access.

var temp02 = json.daily.data[1].apparentTemperatureMax;

A lot of your code is repeated just because you’ve hard coded these indices. Here’s what I would do in your situation:

for (i = 0; i < json.daily.data.length; i++) {

        var temp = Math.round(json.daily.data[i].apparentTemperatureMax);
        $('#temp' + i).html(temp + "&deg;F");
       
        var icon = json.daily.data[i].icon;
        $("#icon" + i).html("<i class='wi wi-forecast-io-" + icon + "'></i>");
}

Change the ids you have in your markup and this should work dandy. This dovetails into your other loop starting on 36. You could probably use the same loop as above, but again, you’d need to change the ids in your markup.

var date = moment().add(i, "day").format("ddd");
$('#day' + i).html(date);

Now, if this seems like a lot of work, that’s because it is. If you’re interested in learning a simple but awesome technique that makes this sort of app much, much easier, then take a look at Handlebars for templating. I have a very simple example on its use here. Take a gander - it’s 24 lines of JavaScript and it should show you everything you need to apply this to your own app. Don’t worry, it’s not a Free Code Camp project, so it’s not cheating to look.

So, changing your temperature for every day in the forecast will be tricky even with templating. Having the data pre-calculated isn’t going to work as well, so it’s kinda like the entirety of my last post was useless drivel :tada:. What I would do is make sure every element that holds a temperature has a class in common (temp would work well). Then, you can use jQuery to select all of those elements.

$('.temp').each(function(index, $element) { //<-- jQuery function
    var currentTemp = $element.html()
    if(tempState === 0) {
      // convert currentTemp to Celcius and reassign to $element.html
    } else {
     // convert currentTemp to Farenheit and reassign to $element.html
})

Hope this post is more helpful!

First, let me say thank you for being so patient with me while working through all of this. Some of my friends just look at my code and tell me I’m not using the correct library and should just do X, Y, and Z instead. But you took the time to show me an option of what I needed to know to answer my question, and so I just want to say Thank you! Thank you! Thank you!

Second, thank you for telling me I was on the right track as I was working through all of this. There are times I’m going through this and wonder if I’ve even on the right track, so thank you for making me feel normal and not completely insane for taking the coding path I chose.

Third, I’m going to give your suggestions a try and see if I can get them to work. I’ll let you know if I run into any hiccups along the way.

Thank you so much again! I really appreciate it! :slight_smile:

2 Likes

Ok so here’s where I’m currently stuck. I’m trying to do the loop you suggested to get the temperature to display. When I go through the loop, it either doesn’t work, shows undefined, or only shows one of the temps in the daily array. Can you show me what I’m missing?

       $.getJSON(fullURL, function(json) {
      //console.log(json);
        
      //Display weather information
     for (i = 0; i < json.daily.data.length; i++) {
         
        var temp = Math.round(json.daily.data[i].apparentTemperatureMax);
        //console.log(temp) + i;
        $('.temp' + i).html(temp + "&deg;F");
     }  

    });

Hey! No worries about helping me out with where I was stuck! A friend of mine helped me get around the part I was stuck on and I FINALLY have things working! And with a loop too! Thank you so much for your help! I might ask you for aid on another problem I’ve been having some trouble with later on if that’s ok? You seem to be someone that knows how to break things down so they’re easy to understand. :slight_smile:

Thank you again!

1 Like