0

I'm currently in the process of creating a weather app which will have two distinct API calls. One for latitude and longitude if the user allows the web app to access location and one where you can search weather by City. However, I am unsure why I keep getting an uncaught reference error telling me that latitude is not defined? As latitude and longitude are both set to equal their respective position.coords in my code. The best I can come up with is maybe a scope issue because of where they are defined, but I need them to be dynamic within the URL string??

Current JavaScript --

let LocationInfo = document.querySelector( ".location-weather" );
const cityInput = document.getElementById( "Search-Bubble" );
const searchButton = document.getElementById( "SearchBtn" );

window.addEventListener( "load", () => {
    let latitude;
    let longitude;
    if ( navigator.geolocation ) {
        navigator.geolocation.getCurrentPosition( ( position ) => {
            latitude = position.coords.latitude;
            longitude = position.coords.longitude;
        })
    }
});

const apiCoordsUrl = `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&exclude=minutely,alerts&units=imperial&appid=${apiTag}`;

async function getCoordsWeatherInfo() {
    const response = await fetch( apiCoordsUrl );
    const data = await response.json();
    this.unveilWeather( data );
};
console.log( getCoordsWeatherInfo() );
Kostas Minaidis
  • 4,681
  • 3
  • 17
  • 25
  • Does this answer your question? [What is the scope of variables in JavaScript?](https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript) – Jared Smith Sep 17 '22 at 23:00

3 Answers3

0

let and const are block scoped so they are only working in your load callback.

you're setting the apiCoordsUrl outside of that scope and also execute getCoordsWeatherInfo outside of the load scope and as such you don't have access to latitude and longitute. They're simply out of scope.

You could move all your other code into the load callback to fix this.

W3School JS Scope

s.Bergmann
  • 194
  • 9
  • Thank you very much, sir. (: So, you're saying that it all needs to be within the load scope? I just want to clarify to make sure I'm understanding you correctly. –  Sep 17 '22 at 22:46
  • yes. edit: added this information into my answer ;) – s.Bergmann Sep 17 '22 at 22:47
  • Thank you very much! I am very new to coding and it is nerve-racking even asking questions sometimes lol. I appreciate your patience! Some people on here are fantastic, others not so much. –  Sep 17 '22 at 22:49
0

It is indeed a scope issue.

Here's a simple setup that will help you execute the weather API with the lat/lon values, bypassing the scope issue:

const LocationInfo = document.querySelector( ".location-weather" );
const cityInput = document.getElementById( "Search-Bubble" );
const searchButton = document.getElementById( "SearchBtn" );

window.addEventListener( "load", () => {
    
    if ( navigator.geolocation ) {
        navigator.geolocation.getCurrentPosition( ( position ) => {
            latitude = position.coords.latitude;
            longitude = position.coords.longitude;
            console.log( getCoordsWeatherInfo( latitude, longitude ) );
        })
    }
});

async function getCoordsWeatherInfo(latitude,longitude) {
    const apiCoordsUrl = `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&exclude=minutely,alerts&units=imperial&appid=${apiTag}`;
    const response = await fetch( apiCoordsUrl );
    const data = await response.json();
    this.unveilWeather( data );
};

As you can see, we need to execute getCoordsWeatherInfo only after we get the lat/lon from the geolocation API.

Since we are passing the lat/lon values as arguments to the function, we don't need to worry about variable scope, just ensure to call the function at the appropriate place.

Hope this helps.

Kostas Minaidis
  • 4,681
  • 3
  • 17
  • 25
0
let LocationInfo = document.querySelector( ".location-weather" );
const cityInput = document.getElementById( "Search-Bubble" );
const searchButton = document.getElementById( "SearchBtn" );

let latitude;  // global scope
let longitude; // global scope

window.addEventListener( "load", () => {
    
    if ( navigator.geolocation ) {
        navigator.geolocation.getCurrentPosition( ( position ) => {
            latitude = position.coords.latitude;
            longitude = position.coords.longitude;
        })
    }


});

const apiCoordsUrl = `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&exclude=minutely,alerts&units=imperial&appid=${apiTag}`;

async function getCoordsWeatherInfo() {
    const response = await fetch( apiCoordsUrl );
    const data = await response.json();
    this.unveilWeather( data );
};



console.log( getCoordsWeatherInfo() );

Try moving your variables declarations to the global space right outside your event listener. This should resolve the not defined error.