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() );
CodePudding user response:
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.
CodePudding user response:
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.
CodePudding user response:
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.