Robert
Robert

Reputation: 25

Global variable assigned value in one function is not accessible in another

I am using geolocation to collect coordinates and make an API call to get the weather in Fahrenheit. I'm assigning the global variable tempNum this value within one of my functions that adds the temperature to the page using function getWeatherByCoordinates(latitude, longitude).

Later, I am trying to access this variable and pass the value as an argument into another function typeConversion for which I am attempting to convert the temperature value to Celsius. It is returning NaN and when debugging, I can't figure out why.

Here is my HTML and JS. I feel like since I declared my variable at the global level and set "return varName" in the function that I assigned the value to it, that the value should be accessible throughout my JS; but I may have done something wrong or misunderstood variable scope. Please assist.

var place = document.getElementById("meat");
var header = document.getElementById("header");

var weather = document.getElementById("Weather");

var latitude;
var longitude;
var coordinates = document.getElementById("coordinates");


function success(position) {
     latitude = position.coords.latitude;
     longitude = position.coords.longitude;
        getWeatherByCoordinates(latitude, longitude);
    };
    //else {
    //    //Write Code to alternatively show a Zip-Code Search Box;
    //};


navigator.geolocation.getCurrentPosition(success);
var city = document.getElementById("city");
var weatherDescription = document.getElementById("weather-description");
var roundTempF;
var roundTempC;
var tempNum;
var tempStringFFull

function getWeatherByCoordinates(latitude, longitude) {
    
    var fullURL = "http://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&APPID=75ed54453a6e806917cfa439b3fb1dd9&units=imperial";

    $.getJSON(fullURL, function (data) {
        
        var tempString = data.main.temp;
        var tempNum = parseInt(tempString);
        roundTempF = Math.floor(tempNum);
        stringF = roundTempF.toString();
        tempStringFFull = stringF + "\xB0" + " F";
        weather.innerText = tempStringFFull;
        city.innerText = data.name;
        weatherDescription.innerText = data.weather[0].description;

        if (data.dt > data.sys.sunrise && data.dt < data.sys.sunset) {
            $("#whole-page").removeClass("whole");
            $("#whole-page").removeClass("night");
            $("#whole-page").addClass("day");
        }
        else {
            $("#whole-page").removeClass("whole");
            $("#whole-page").removeClass("night");
            $("#whole-page").addClass("night");
        };

        event.preventDefault();
    });
    return tempNum;
};



function typeConversion(tempNum) {
    if (changeTempType.innerText === "Celsius") {
        var tempStringC;
        var celsiusDecimal = (tempNum - 32) * (5 / 9);
        roundTempC = Math.floor(celsiusDecimal);
        tempStringC = roundTempC.toString();
        tempStringC += "\xB0" + " C";
        weather.innerText = tempStringC;
        changeTempType.innerText = "Farenheit";
        return;
    }
    else if (changeTempType.innerText === "Farenheit") {
        weather.innerText = tempStringFFull;
        changeTempType.innerText = "Celsius";
        return;
    }
    else {
        weather.innerText = "We are unable to retrieve the weather at this time.  Please try again later";
        changeTempType.innerText = "Celsius";
        return;
    };
};

var changeTempType = document.getElementById("change-temp-type");

changeTempType.addEventListener("click", typeConversion, false);
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet"/>
    <link rel="stylesheet" type="text/css" href="css/style.css" />
    <script defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
    <title>Weather</title>
</head>
<body id="whole-page" class="whole">
    <div class="wrapper"> 

       
    <h2 id="header">Check the Current Temperaturate by Zip Code</h2>
<label>Farenheit</label>
    <input type="radio" name="temp-type" value="C" id="Celsius-radio"/><label>Celsius</label>-->
        <button id="change-temp-type">Celsius</button>

     <form>    
      <p>Enter the Zip Code to see the Weather there!</p>
      <input id = "Zip-Code" type="text"/>
      
      <input id = "submit-zip" type="button" value="Get Weather!"/>
    </form>
    <div>
            
            <h3 id="city"></h3>
            <h3 id= "Weather" class="temp-text"></h3>
            <h4 id="weather-description"></h4>

      </div>
       
    </div>
<script src= "https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"> </script> 
   
<script src="javascript/main.js"></script>
</body>
</html>

Upvotes: 1

Views: 53

Answers (1)

arbuthnott
arbuthnott

Reputation: 3819

You have a couple of issues:

  1. You re-declare var tempNum = in your function, meaning it will be a new variable only accessible inside the function scope (leaving the global one unchanged)
  2. Your code inside of $.getJSON is using an asynchronous callback - that means it will run sometime later than the code below it. When you return tempNum, that code has not run yet.
  3. Your return statement isn't really doing anything... just reassigning the global variable will be sufficient.

UPDATE - issue I missed at first:

  1. You are naming your function parameter in typeConversion "tempNum". Again, that will result in a new variable, only accessible within the scope of that function. If you want to affect the global, then this function does not need any parameters at all, and tempNum will then refer to the global variable as intended.

I've tried to clear up all issues below.

var place = document.getElementById("meat");
var header = document.getElementById("header");

var weather = document.getElementById("Weather");

var latitude;
var longitude;
var coordinates = document.getElementById("coordinates");


function success(position) {
     latitude = position.coords.latitude;
     longitude = position.coords.longitude;
        getWeatherByCoordinates(latitude, longitude);
    };
    //else {
    //    //Write Code to alternatively show a Zip-Code Search Box;
    //};


navigator.geolocation.getCurrentPosition(success);
var city = document.getElementById("city");
var weatherDescription = document.getElementById("weather-description");
var roundTempF;
var roundTempC;
var tempNum;
var tempStringFFull

function getWeatherByCoordinates(latitude, longitude) {
    
    var fullURL = "http://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&APPID=75ed54453a6e806917cfa439b3fb1dd9&units=imperial";

    $.getJSON(fullURL, function (data) {
        
        var tempString = data.main.temp;
        // removed "var tempNum"...
        tempNum = parseInt(tempString);
        roundTempF = Math.floor(tempNum);
        stringF = roundTempF.toString();
        tempStringFFull = stringF + "\xB0" + " F";
        weather.innerText = tempStringFFull;
        city.innerText = data.name;
        weatherDescription.innerText = data.weather[0].description;

        if (data.dt > data.sys.sunrise && data.dt < data.sys.sunset) {
            $("#whole-page").removeClass("whole");
            $("#whole-page").removeClass("night");
            $("#whole-page").addClass("day");
        }
        else {
            $("#whole-page").removeClass("whole");
            $("#whole-page").removeClass("night");
            $("#whole-page").addClass("night");
        };

        event.preventDefault();
    });
    //return tempNum;
};


// removed the argument "tempNum", just use the global
function typeConversion() {
    if (changeTempType.innerText === "Celsius") {
        var tempStringC;
        var celsiusDecimal = (tempNum - 32) * (5 / 9);
        roundTempC = Math.floor(celsiusDecimal);
        tempStringC = roundTempC.toString();
        tempStringC += "\xB0" + " C";
        weather.innerText = tempStringC;
        changeTempType.innerText = "Farenheit";
        return;
    }
    else if (changeTempType.innerText === "Farenheit") {
        weather.innerText = tempStringFFull;
        changeTempType.innerText = "Celsius";
        return;
    }
    else {
        weather.innerText = "We are unable to retrieve the weather at this time.  Please try again later";
        changeTempType.innerText = "Celsius";
        return;
    };
};

var changeTempType = document.getElementById("change-temp-type");

changeTempType.addEventListener("click", typeConversion, false);
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet"/>
    <link rel="stylesheet" type="text/css" href="css/style.css" />
    <script defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
    <title>Weather</title>
</head>
<body id="whole-page" class="whole">
    <div class="wrapper"> 

       
    <h2 id="header">Check the Current Temperaturate by Zip Code</h2>
<label>Farenheit</label>
    <input type="radio" name="temp-type" value="C" id="Celsius-radio"/><label>Celsius</label>-->
        <button id="change-temp-type">Celsius</button>

     <form>    
      <p>Enter the Zip Code to see the Weather there!</p>
      <input id = "Zip-Code" type="text"/>
      
      <input id = "submit-zip" type="button" value="Get Weather!"/>
    </form>
    <div>
            
            <h3 id="city"></h3>
            <h3 id= "Weather" class="temp-text"></h3>
            <h4 id="weather-description"></h4>

      </div>
       
    </div>
<script src= "https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"> </script> 
   
<script src="javascript/main.js"></script>
</body>
</html>

Last note - this will work fine if the function where you need to access tempNum runs later, like in response to a user action. It may still be undefined for a few ms after your page loads, so if you try to use it right at page load time, it may still be undefined. You may want to initialize it to some default value in this case.

Hope this helps.

Upvotes: 2

Related Questions