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 useEffect
s 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)
})();
}, []);