[Weather App] - can't change from C to F. Don't know how to pass in the temperature and then save it into the click function

[Weather App] - can't change from C to F. Don't know how to pass in the temperature and then save it into the click function
0

#1

Hi guys,

I have a problem.
Working since hours on my weather app. It’s now getting the weather based on the users location. The last part of the puzzle is to change F to C. But it’s not working. I’m now at the point where I’m stuck since hours and google etc. didn’t help me out.

I try to explain it to you now:

At first here is my codepen: https://codepen.io/GeraltDieSocke/pen/yzJrBg

My idea was to set up a function which takes a temperature. In this function there is a onclick method for the temperature

tag on the site.

Then I also added a global variable on top var fahrenheit = true.
So it’s defaulted to true.

The function itself looks as followed (I left comments to make my intentions clear):

function changeMetric(temperature) {
  // save the temperature in the method just for safety
  var temp = temperature;
  // select the temperature p tag and add on click function
  $(".temperature").on("click", function() {
    //check if fahrenheit is true and if yes apply the formula
   if(fahrenheit === true) {
     // convert to Celsius 
     temp = Math.round(temp * 9 / 5 + 32);
     // update p tag with the new temp + C
     $(".temperature").text(temp + "°C");
     // set the variable to false for the next click so the "else" can triger
     fahrenheit = false;
   } else {
     //convert to fahrenheit
     temp = Math.round((temp  -32) * 5 / 9);
     // same as above
     $(".temperature").text(temp + "°F");
     fahrenheit = true;
   }
    // console log for checking. The Console log looks like this:
    // when the first click happens (starting value of 55F)
    // NaN false
    // 13 true
    // second click on p tag:
    // NaN false
    // -11 true
    console.log(temp, fahrenheit);
  });  
}

So as you can see in my comments this is he weird console output. It also changes the values in the p tag to this weird numbers.
So first click => 13°F
Second click => -11°F
… it stops after 8 clicks and -39°F

So where is my big mistake? Now you wonder when do I call the function and pass in the method?
In my getWeather function at the end after everything is updated:
changeMetric(temperature); (see also in the codepen).
Now the question: Is a click event always listening and always gets called on a click?. Because the click event is inside this function. So how does this work and can I do this? Is it still listening altough it’s inside another function which first has to be “called” ?

Please help me out here I think I made some big mistakes.

Help very much appreciated :slight_smile:
Thanks guys!!


#2

You need to get rid of the changeMetric function all together, because it is part of the problem. Once you have done that, then you can put the following click event listener for the element with class=“temperature”.

      $(".temperature").on("click", function() {
        //check if fahrenheit is true and if yes apply the formula
        if (fahrenheit === true) {
          // convert to Celsius
          var temp = Math.round((temperature - 32) * 5 / 9);
          // update p tag with the new temp + C
          $(".temperature").text(temp + "°C");
          // set the variable to false for the next click so the "else" can triger
          fahrenheit = false;
        } else {
          // no need to convert because temperature already is in Fahrenheit
          $(".temperature").text(temperature + "°F");
          fahrenheit = true;
        }
      });

on the line after the following:

getWeather(location, temperature, text);

Your original anonymous function for the click event had the wrong formula for converting to Celsius. Also, you will notice in my version above, there is no need to convert back to Fahrenheit, because the temperature variable was already in Fahrenheit.


#3

You are the man!!
Thank you it’s working now.

Also very good explained.

One more thing:

If I want to make the code more readable (because the function is already so cluttered and long). Do I need to put the onclick into the same method due to the variable scope?
How can I outsource this into a method?


#4

You could create a stand alone function called toggleTemp and use it for the callback of the click event.

function toggleTemp(temperature) {
  //check if fahrenheit is true and if yes apply the formula
  if(fahrenheit === true) {
    var temp = Math.round((temperature -32) / 1.8); // convert to Celsius 
    $(".temperature").text(temp + "°C");
    fahrenheit = false;
  }
  else {
    $(".temperature").text(temperature + "°F");
    fahrenheit = true;
  }
}

Then if you want, you could put the click event at the end of your setWeather function like:

function setWeather(location, temperature, text) {
  $(".country").text(location);
  $(".temperature").text(temperature + "°F");
  $(".status").text(text);
  $(".temperature").on("click", function(){ toggleTemp(temperature) }); 
}

#5

Ah yes. Instead of creating the code in the callback function I just create a seperate function and pass it in as callback.

Thank you Mr!