0

I'm looking for a solution on how to fire function when all requests have been finished.

I'm using React Query to manage external data state and useMutation hook because I need to re-fetch data on select change.

const fetcher1 = async () => await axios.get('XXX');
const fetcher2 = async () => await axios.get('XXX');

const { data, isLoading, mutate: fetchData1 } = useMutation(fetcher1)
const { data2, isLoading: isLoading2, mutate: fetchData2 } = useMutation(fetcher2)

function runWhenReady() {
 console.log("Ready!")
}

// re-fetch on select change and initial fetch
useEffect(() => {
 fetchData1();
 fetchData2();
}, [selectValueChanged])

I want to watch for request state change and fire runWhenReady() when all of the requests are not pending. I suppose I need to wait for e.g 1s to make a decision.

Could anyone help me with preparing utility to monitor request states? Thanks!

Dominik
  • 1,265
  • 1
  • 16
  • 27

2 Answers2

2

You can look at isSuccess to see when a successful request has happend.

const { data, isLoading, mutate: fetchData1, isSuccess: 1isSuccess } = useMutation(fetcher1)
const { data2, isLoading: isLoading2, mutate: fetchData2, isSuccess: 2isSuccess } = useMutation(fetcher2)


useEffect(() => {
  if(1isSuccess && 2isSuccess){
    runWhenReady();
  }
}, [1isSuccess, 2isSuccess]);
hellogoodnight
  • 1,989
  • 7
  • 29
  • 57
1

mutateAsync and Promise.allSettled is likely what you are looking for, because mutateAsync returns a normal promise that you can chain together. Be aware that you have to catch errors yourselves or you'll see unhandled promise rejections.

const { data, isLoading, mutateAsync: fetchData1, isSuccess: 1isSuccess } = useMutation(fetcher1)
const { data2, isLoading: isLoading2, mutateAsync: fetchData2, isSuccess: 2isSuccess } = useMutation(fetcher2)

<button onClick={() => {
    Promise.allSettled([fetchData1(), fetchData2()])
        .then(results => runWhenReady())
        .catch(...)
} />
TkDodo
  • 20,449
  • 3
  • 50
  • 65