Search code examples
reactjsfetch-apiuse-effect

Fetch API React Js Unexpected token < in JSON at position 0


I got this error from my fetch api when I pass my url fetch API from a state called url. But when I changed my url into text like 'api/provinsi' I don't get any error

Error fetching data: SyntaxError: Unexpected token < in JSON at position 0

   useEffect(() => {
        async function fetchMyAPI() {
            await fetch(url, {
                method: 'GET'
            }).then(response => {
                if(!response.ok) {
                    throw new Error(response.statusText);
                }
                return response.json();
            })
            .then(response => {
                if(response.Response === 'False') {
                    throw new Error(response.Error);
                }
                setData(response.data);
            }).catch(error => {
                console.log("Error fetching data: ", error);
            });
        }
        fetchMyAPI();
    }, []);

And this is how I set my url state:

  useEffect(() => {
        if(idDaerah==1){
            setColumn(['no', 'nama', 'aksi']);
            setUrl('/api/provinsi');
        } else if(idDaerah==2) {
            setColumn(['no', 'nama', 'provinsi_id', 'aksi']);
            setUrl('/api/kabupaten');
        } else if(idDaerah==3) {
            setColumn(['no', 'nama', 'kabupaten_id', 'aksi']);
            setUrl('/api/kecamatan');
        } else {
            setColumn(['no', 'nama', 'kecamatan_id', 'aksi']);
            setUrl('/api/desa');
        }
    }, []);

Solution

  • Because both useEffect runs at the same time, and the fetch function receive url as an empty string first time, so you need to add url as dependency.

    useEffect(() => {
            async function fetchMyAPI() {
                await fetch(url, {
                    method: 'GET'
                }).then(response => {
                    if(!response.ok) {
                        throw new Error(response.statusText);
                    }
                    return response.json();
                })
                .then(response => {
                    if(response.Response === 'False') {
                        throw new Error(response.Error);
                    }
                    setData(response.data);
                }).catch(error => {
                    console.log("Error fetching data: ", error);
                });
            }
           if(url !== ''){ //check if url is set i.e not an empty string
            fetchMyAPI();
          }
        }, [url]); //add dependency, when url change then call api
    

    OR

    You can provide a default url like:

    const [url, setUrl] = useState('/api/provinsi');