Stuck trying to switch between Fahrenheit and Celsius [SOLVED]

Stuck trying to switch between Fahrenheit and Celsius [SOLVED]
0.0 0

#1

Pen here: http://codepen.io/transmothra/pen/ryvYzm

I have been trying to figure out what i’m doing wrong here. I’ve gotten to the point where i’m trying to allow the user to switch between imperial and metric units, but i’m not entirely sure how to go about it. What i think i’m trying to do in the current version is that when the user clicks on the F or C, the main weather function should be run again but with the variable “units” set to the opposite of whichever is currently set (default is imperial, because i live in a country with breathtaking scientific illiteracy). However, my own programming illiteracy is leaving me withered and frustrated.

$("#unit").click(function() { units = units === "imperial" ? "metric" : "imperial"; weather(); });

What have i missed here? Thanks for any help/advice/suggestions!


#2

I took the approach of only calling the API once, but instantiating both variables at the same time. So I get the temp (in kelvins, but that doesn’t matter) and create a variable for C° and F°, then I load the C° value by default, and when the user clicks the toggle button, it just swaps the variable - no return trip to the weather API needed.


#3

You should pass the units as an argument to the weather function and not declare them as a variable in the weather function.

As the code stands above even if you change units via a click unless you pass on that change to the function it will always run with the same parameters

function weather(units) {
 console.log(units);
};

weather('imperial'); // 'imperial'
weather('metric'); // 'metric'

what you’re doing at the moment is a little like this

function weather() {
 var units = 'imperial';
 console.log(units);
};

weather(); // 'imperial'
var units = 'metric';
weather(); // still 'imperial'

Hope that makes sense!


#4

In your code this function

$("#unit").click(function() {
  units = units === "imperial" ? "metric" : "imperial";
  weather();
});

it executed before the #unit element is added to the page, therefore code above is not called when the F is clicked.


#5

Sorry for resurrecting an old thread, but life happened, and now i’m back at it, and still cannot figure this thing out. I’ve updated my code a little bit, but am still having a hell of a time trying to find out where i’m going wrong. I feel like i should scrap it and start over but i’m not sure what’s salvageable and what’s trash. Help!

$(document).ready(function() {
  var units = "imperial";

  function weather(units) {
    $.getJSON("http://ip-api.com/json", function(data) {
      var city = data.city;
      var latitude = data.lat;
      var longitude = data.lon;
      $("#city").html("City: " + city);
      $("#lat").html("— Latitude : " + latitude);
      $("#lon").html("| Longitude: " + longitude);

      makeWeather(latitude, longitude);
    })

    function makeWeather(latitude, longitude) {
      var url = "http://api.openweathermap.org/data/2.5/weather"
      var key = "573edd366b425b7f59d4ec608b063f24";
      var weatherAPI = url + "?lat=" + latitude + "&lon=" + longitude + "&units=" + units + "&appid=" + key;
      $.getJSON(weatherAPI, function(displayWeather) {
        var temp = Math.round(displayWeather.main.temp);
        var tempF = temp;
        var tempC = (temp -32) * 5 / 9;
        var humidity = displayWeather.main.humidity;
        unit = units === "imperial" ? "F" : "C";

        $("#temp").html("Temperature: " + temp + "&deg;<a href=\"#\" id=\"unit\"></a>");
        $("#unit").html(unit);
        $("#humidity").html("Humidity: " + humidity + "%");
      });
    };
  };
  $("#unit").click(function() {
    if (units == "imperial") {
      temp = tempC;
      units = "metric";
    }
    else temp = tempF;
    units = "imperial";
  });
  weather(units);
});

#6

Can you post a link to the actual pen?

And just for the heck of it, my approach (of which I’m probably undeservedly overly proud) was to write both imperial and metric data to the page, but encapsulate each in a span with classes “imperial” and “metric”. Then I had a button that toggles the visibility of those classes. Worked nicely

I’m still waiting for someone to test my page. cough


#7

It’s at the top of the thread: http://codepen.io/transmothra/pen/ryvYzm

Yours works nicely. Good idea on that.


#8

I’ve changed around my code a bit but i’m still stuck. Can somebody tell me what i’m doing wrong?


#9

Nevermind. What i ended up doing is splitting up the #temp div into a #degree span and a #unitSymbol span, which for whatever reason (i honestly have no clue why) seems to have worked.


#10

It looks like you figured it out, but this bit of code was probably the problem. Since your “else” did not have brackets, only the first line was getting evaluated. So even though you intended for units to be set to imperial only in the “else” case, units was always getting set to imperial.


#11

That’s one of the things i did change, yep! Thanks!

Now i’m trying to determine if it’s day or night and having a hard go at it. Where am i going wrong?

var sunrise = displayWeather.sys.sunrise * 1000;
var sunset = displayWeather.sys.sunset * 1000;
var now = Date.now();
var dayOrNight;
if (now < sunrise < sunset || sunset < now < sunrise) {
  dayOrNight = "night";
  $("#weather").css("background-color","#000");
  $("body").css({"color":"#fff","background-color":"#333"});
}
else if (now < sunset < sunrise || sunrise < now < sunset) {
  dayOrNight = "day";
  $("body").css({"color":"#000","background-color":"#ccc"});
}