I am working with OpenWeatherMap in order to grab the current weather of, say, Helsinki.
My latest MNWE (N as non
) is:
import axios from 'axios'
const apiKey = import.meta.env.VITE_OWM_API_KEY
const getCityCoordinatesApiUrl = (city) => {
return `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`
}
const getCityWeatherApiUrl = (longitude, latitude) => {
return `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&appid=${apiKey}`
}
const getCityWeather = (city, weatherJsonContainer) => {
const url = getCityCoordinatesApiUrl(city)
let longitude = null
let latitude = null
axios.get(url).then(response => {
console.log("Hell", response.data)
longitude = response.data.coord.lon
latitude = response.data.coord.lat
})
.catch(error => {
console.log("Error in getCityWeather:", error)
alert(`Could not obtain weather of ${city}!`)
})
console.log("getCityWeather: received:", latitude, longitude)
const url2 = getCityWeatherApiUrl(longitude, latitude)
const outData = axios.get(url2).then(response => response.data)
console.log("getCityWeather: outData:", outData)
}
My problem is that longitude
and latitude
stay as null
. How can I resolve this issue? I have been working on it for several hours now.
Edit 1
After trying code kindly provided by urchmaney, my problematic implementation transforms into the following:
import axios from 'axios'
const apiKey = import.meta.env.VITE_OWM_API_KEY
const getCityCoordinatesApiUrl = (city) => {
return `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`
}
const getCityWeatherApiUrl = (longitude, latitude) => {
return `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&appid=${apiKey}`
}
const getCityWeather = (city) => {
const url = getCityCoordinatesApiUrl(city)
axios.get(url).then(response => {
const longitude = response.data.coord.lon
const latitude = response.data.coord.lat
const url2 = getCityWeatherApiUrl(longitude, latitude)
return axios.get(url2);
})
.then(response => {
console.log(response.data)
return response.data
})
.catch(error => {
console.log("Error in getCityWeather:", error)
alert(`Could not obtain weather of ${city}!`)
})
}
export default {
getCityWeather
}
(Calling the above)
const weatherJsonData = weatherService.getCityWeather('Helsinki')
Now, my problem is in the 2nd then
: return response.data
returns undefined
.
3
Answers
you need to wait for 1st request to finish. Put the code after .catch() in a .then() statement
You need to chain the API calls. The way you are trying to access the longitude and latitude is not in the right context. the assignment line
console.log("getCityWeather: received:", latitude, longitude)
is ran before the API call is returned.To chain the API call you will do like this
Async / Await Implementation
Remember it is an async method so you need to await it when consuming it
Send the city, lat, lon, appid as query params. I have altered the api call url based on this docs.
Try using async-await for better promises handling.
I have removed the two functions as the urls are same and sent the data using axios params.
This will resolve the issue.
Using .then() and .catch():
Changes in your code:
reactjsaxios