Search code examples
reactjsapiuse-effect

How can I use response data from an API to call another different API request in React UseEffect?


I was wondering how can I call an API that requires data from other API. In my case I want to get the coordinates; lattitude and longitute and make another API call with these to retrieve the information I need.

Here is App.js file

import React from 'react';
import './App.css';
import CityInput from "./components/CityInput";
import {Container} from 'react-bootstrap';
import UseFetch from "./hooks/useFetch";
import {API_BASE_URL, API_KEY} from "./apis/config";
import WeatherList from "./components/WeatherList";

const App = () => {
    const {data, error, isLoading, setUrl} = UseFetch();

    const getContent = () => {
        if(error) return <h2>Error when fetching: {error}</h2>
        if(!data && isLoading) return <h2>LOADING...</h2>
        if(!data) return null;
        return <WeatherList weathers={data.list}/>
    };

    return (
      <Container className="App">
          {/* user types a city and clicks search*/}
          <CityInput onSearch={(city) => setUrl(`${API_BASE_URL}/data/2.5/forecast?q=${city}&appid=${API_KEY}&units=metric`)} />

          {getContent()}

      </Container>
    );
}

export default App;

and here is my UseFetch.js file

import {useState, useEffect} from 'react';
import {API_BASE_URL, API_KEY} from "../apis/config";

const UseFetch = (initialUrl) => {
    const [data, setData] = useState(null);
    const [error, setError] = useState(null);
    const [isLoading, setIsLoading] = useState(null);
    const [url, setUrl] = useState(initialUrl);

    useEffect(() => {
        if(!url) return;
        setIsLoading(true);
        setData(null);
        setError(null);

        fetch(url)
            .then((response) => response.json())
            .then((data) => {
                setIsLoading(false);
                if(data.cod >= 400) {
                    setError(data.message);
                    return;
                }
                setData(data);
                console.log(data);

                console.log(data.city.coord.lat);
                console.log(data.city.coord.lon);


            })
            .catch((error) => {
                setIsLoading(false);
                setError(error);
            });
        //
        // console.log('HIIIIII'+ data);
        // fetch(`${API_BASE_URL}/data/2.5/onecall?lat=${data.city.coord.lat}&lon=${data.city.coord.lon}&exclude=minutely&appid=${API_KEY}`)
        //     .then((response) => response.json())
        //     .then((data2) =>  {
        //         setIsLoading2(false);
        //         setData2(data2);
        //         console.log(data2);
        //     })
        //     .catch((error2) => {
        //         setIsLoading2(false);
        //         setError2(error);
        //     });
    }, [url]);
    return { data, error, isLoading, setUrl};


};

export default UseFetch;

I want to retrieve lantitude and lontitude so i can make another fetch

fetch(`${API_BASE_URL}/data/2.5/onecall?lat=${data.city.coord.lat}&lon=${data.city.coord.lon}&exclude=minutely&appid=${API_KEY}`)

But this doesnt seem to work. I'm using these API for reference:

https://openweathermap.org/forecast5

https://openweathermap.org/api/one-call-api


Solution

  • Call it right after the Initial Api sends back the response for example:

    fetch(APIURL)
    .then(response => {
    /** do any operations using received response data **/
    
    /** Calling second api **/
    fetch(API_URL_ + response.data.url)
    .then(data => {
    setData(data)
    })
    .catch(error)
    }).catch(error)
    

    UseFetch.js

    import {useState, useEffect} from 'react';
    import {API_BASE_URL, API_KEY} from "../apis/config";
    
    const UseFetch = (initialUrl) => {
        const [data, setData] = useState(null);
        const [error, setError] = useState(null);
        const [isLoading, setIsLoading] = useState(null);
        const [url, setUrl] = useState(initialUrl);
    
        useEffect(() => {
            if(!url) return;
            setIsLoading(true);
            setData(null);
            setError(null);
    
            fetch(url)
                .then((response) => response.json())
                .then((data) => {
                    setIsLoading(false);
                    if(data.cod >= 400) {
                        setError(data.message);
                        return;
                    }
                    setData(data);
                    console.log(data);
    
                    console.log(data.city.coord.lat);
                    console.log(data.city.coord.lon);
    
      console.log('HIIIIII'+ data);
    fetch(`${API_BASE_URL}/data/2.5/onecall?lat=${data.city.coord.lat}&lon=${data.city.coord.lon}&exclude=minutely&appid=${API_KEY}`)
                 .then((response) => response.json())
                 .then((data2) =>  {
                     setIsLoading2(false);
                     setData2(data2);
                     console.log(data2);
                 })
                 .catch((error2) => {
                     setIsLoading2(false);
                     setError2(error);
                });
    
                })
                .catch((error) => {
                    setIsLoading(false);
                    setError(error);
                });
            
        }, [url]);
        return { data, error, isLoading, setUrl};
    
    
    };
    
    export default UseFetch;