I'm very new to React and web development as a whole, and I know the code is styled terribly but bear with me please.
I'm attempting to get weather data with openweathermap API, which I have to use latitude and longitude for my desired location, which I am supposed to get from their separate geocoding API when I feed it the capital and country code of a country I'm interested in.
I'm kind of unsure how to "stack" these requests so that the first coordinate request goes through and gives the coordinates to the second, weather request. My problem, is that the coordinates (which I otherwise get successfully) are given as undefined to my next request, and I can't figure out why, and I've tried a lot.
const Content = ({result}) => {
const languages = [result['languages']]
const [weather, setWeather] = useState([])
const [coordinate, setCoordinates] = useState([])
const api_key = process.env.REACT_APP_API_KEY
useEffect(() => {
axios
.get(`http://api.openweathermap.org/geo/1.0/direct?q=${result['capital']},${result['cca2']}&limit=1&appid=${api_key}`)
.then(response => {
setCoordinates(response.data)
})
.then(() =>
axios
.get(`https://api.openweathermap.org/data/3.0/onecall?lat=${coordinate['lat']}&lon=${coordinate['lon']}&exclude=1&appid=${api_key}`)
.then(response => {
setWeather(response.data)
}))
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
CodePudding user response:
setCoordinates
does not update coordinate
immediately, as React batches state updates. States are therefore updated asynchronously.
If your second request is dependent on state changes to the coordinate
array, then you should move it into its own useEffect
hook:
const Content = ({result}) => {
const languages = [result['languages']]
const [weather, setWeather] = useState([])
const [coordinate, setCoordinates] = useState([])
const api_key = process.env.REACT_APP_API_KEY
useEffect(() => {
axios
.get(`http://api.openweathermap.org/geo/1.0/direct?q=${result['capital']},${result['cca2']}&limit=1&appid=${api_key}`)
.then(response => {
setCoordinates(response.data)
});
}, []);
// Your second API call is dependent on state changes to `coordinate`
useEffect(() => {
axios
.get(`https://api.openweathermap.org/data/3.0/onecall?lat=${coordinate['lat']}&lon=${coordinate['lon']}&exclude=1&appid=${api_key}`)
.then(response => {
setWeather(response.data)
});
}, [coordinate]);
};
CodePudding user response:
const Content = ({result}) => {
const languages = [result['languages']]
const [weather, setWeather] = useState([])
const [coordinate, setCoordinates] = useState([])
const api_key = process.env.REACT_APP_API_KEY
useEffect(() => {
let coordinateResult = [];
axios
.get(`http://api.openweathermap.org/geo/1.0/direct?q=${result['capital']},${result['cca2']}&limit=1&appid=${api_key}`)
.then(response => {
coordinateResult = response.data;
})
.then(() =>
axios
.get(`https://api.openweathermap.org/data/3.0/onecall?lat=${coordinateResult['lat']}&lon=${coordinateResult['lon']}&exclude=1&appid=${api_key}`)
.then(response => {
setCoordinates(coordinateResult);
setWeather(response.data)
}))
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
Focus that setState
function is asynchronous.