Home > Net >  How to fetch API and store some value and then fetch again with that stored value in React
How to fetch API and store some value and then fetch again with that stored value in React

Time:10-05

Currently I am fetching some data and I save the response via useState. The response is saved but the problem is the second fetch takes place before the state was saved making that value undefined.

I tried to do like this:

  useEffect(() => {
    fetchTrackingData().finally(() => {
      console.log("Destination", destination.coordinates);
      fetchDriverLocation().finally(() => {
        setLoading(false);
      });
    });
  }, []);

Basically fetchTrackingData function has destination coordinates which I save with:

const [destination, setDestination] = useState('');

In the fetchTrackingData function I am setting the state after receiving the response. After fetchTrackingData is done fetching and it has saved state of destination I then use finally() method and then call the second fetch which is fetchDriverLocation but it has destination undefined and even I logged to see if the value gets saved after finally() but it is undefined in log as well.

How can I store the value from one API in that API call and then use that value in another API call?

CodePudding user response:

What you're experiencing is a race condition.

When you call fetchTrackingData, it makes the HTTP request to your API, gets a response and then the last thing it does is saves destination to the state. But when you call setDestination, this is another asynchronous task that is kicked off, then you move directly to trying to access it from the state (which it may or may not be there, depending on how long it takes to set the state).

My recommendation would be to either not rely on state for this process (perhaps a variable will do? or even just passing along the result of your http request) or to lean more heavily on chaining these Promises and have the setting of the state be included in the Promise chain. However, I would favour the former suggestion

See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

and: Chain React setState callbacks

CodePudding user response:

As another answer has stated, you are experiencing a race condition because setState in react is often asynchronous.

My suggestion would be to use two useEffects to accomplish this:

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

useEffect(() => {
  console.log("Destination", destination.coordinates);
  fetchDriverLocation().finally(() => {
    setLoading(false);
  });
}, [destination]);

The above will wait until destination changes before moving on with fetching the driver location

CodePudding user response:

You can try with the async await methods and call the other APIs after the first one is done.

Example :

function App() {
  const [data, setData] = useState();
  const [data2, setData2] = useState();

  useEffect(() => {
    (async () => {
      const response = await fetch("someURL");
      const json = await response.json();
      setData(json);
      const responseList = await fetch("someURL"   json.data);
      const jsonData = await responseList.json();
      setData2(jsonData)
    })();
  }, []);


  return (
    <div>
        Hello
    </div>
  );
}

export default App;

CodePudding user response:

by using useEffect fetching data from firstURI and sending to secondURI

  const [firstDate, setFirstData] = useState();
  const [secondDate, setSecondData] = useState();

  useEffect(() => {
    (async () => {
      const firstResponse = await fetch("firstURI");
      const firstResponseData = await firstResponse.json();
      setFirstData(firstResponseData);
      
      const secondResponse = await fetch("secondURI"   firstResponseData.data);
      const secondResponseData = await secondResponse.json();
      setSecondData(secondResponseData)
    })();
  }, []);
  • Related