Home > Software design >  fetch returns first empty array, after that it returns response
fetch returns first empty array, after that it returns response

Time:01-16

I'm making my final degree project and now I'm involved in the part to show towns on a map using data from a backend URL.

The problem is that fetch returns at first an empty array, and I need it to stay loading until the variable is a valid JSON.

    const [isLoading, setLoading] = useState(true);
    const [markers, setMarkers] = useState([]);

    const getTowns = async () => {
        try {
            const response = await fetch(`${baseUrl}/towns`);
            const json = await response.json();
            setMarkers(json.data);
        } catch (error) {
            console.error(error);
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        getTowns();
    }, []);

Another question is: Why when I put a console.log('whatever') it appears more than one time on the console. Don't understand why

What I need is fetch to setLoading(false) only when response is a JSON, not an empty array

CodePudding user response:

What you can do is add these 2 hooks to your code:

  • A state for the returned response (with initial value an empty array)
  • A useEffect which will set to false isLoading once the response state change value

const [response, setResponse] = useState([]);

const getTowns = async () => {
    try {
        setResponse(() => await fetch(`${baseUrl}/towns`));
        const json = await response.json();
        setMarkers(json.data);
    } catch (error) {
        console.error(error);
    }
};

useEffect(() => {
    setLoading(() => false);
}, [response]);

CodePudding user response:

your code is fine you juste don't need the isLoading useState Hook. you can test with the value of markers

Why when I put a console.log('whatever') it appears more than one time on the console. Don't understand why

when the component first render getTowns runs in useEffect and since it updates the state the component renders again. learn more here about react component lifecycle

what I suggest is when you are returning your jsx you check if markers is still empty

const [markers, setMarkers] = useState('');

if(markers === ''){
return (<div>Loading...<div/>)
} else {
return(<>
.... what you need to return in you component
</>)
}
  • Related