Search code examples
jsonreactjsreact-hooksuse-effectuse-state

Getting responses from two interdependent JSON generates an error [React Hooks]


I want to download the data first about the city in which the user is located from ipstack.com and then use this information to generate the weather using openweather.com. However, the following problem occurs during render:

Test.js:20 GET https://api.openweathermap.org/data/2.5/weather?lat=undefined&lon=undefined&units=metric&appid=(MY API KEY) 400 (Bad Request)

The problem is strange because the data I require appears in state eventually:

enter image description here

My code:

import React, { useState, useEffect } from 'react';

const Test = () => {
    const [place, setPlace] = useState([]);
    const [weather, setWeather] = useState([]);
    const [loading, setLoading] = useState(false);

    useEffect(() => {
        setLoading(false)
        fetch(`http://api.ipstack.com/check?access_key=(MY API KEY)`)
            .then(result => result.json())
            .then(json => {
                setPlace([json.latitude, json.longitude, json.region_name])
            })
            .catch(err => {
                console.log("Error " + err);
            })
    }, [])
    useEffect(() => {
        fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${place[0]}&lon=${place[1]}&units=metric&appid=(MY API KEY)`)
            .then(result => result.json())
            .then(json => {
                setWeather(json)
            })
            .catch(err => {
                console.log("Error " + err);
                setLoading(true);
            })
    }, [place])
    return (
        <>
            {loading && (
                <>
                    <p>{place[0]}</p>
                    <p>{place[1]}</p>
                    <p>{place[2]}</p>
                    <p>{weather.name}</p>
                </>
            )}
        </>
   );
}

export default Test;

Solution

  • I think in the second effect you should fetch data from openweathermap.org only if place array assigned and has correct data. Otherwise on first run you will send invalid data (undefineds instead of positions)