Home > Software design >  wait for multiple API calls to finish using useAxios custom hook
wait for multiple API calls to finish using useAxios custom hook

Time:01-06

I use useAxios custom hook to avoid the code duplicity as the API I am calling is always the same.

import { useState, useEffect } from 'react';
import rest from './rest';     // inside there is a definition of axios.create baseURL...       

const useAxios = (endpoint,queryString) => {

  const [axiosData, setAxiosData] = useState(null);
  const [axiosLoading, setAxiosLoading] = useState(true);

  useEffect(() => {

    const getRest = async () => {
      setAxiosLoading(true);
      try{
        const sensors  = await rest
        .get('/'  endpoint   '?'   queryString)
        .then(res => {
          setAxiosData(res.data);
          setAxiosLoading(false);
        });
      }catch (e) {
        console.log(e);
      }
    }

    getRest(); 

  }, [endpoint,queryString])

  return {axiosData, axiosLoading}; 

}
export default useAxios;

Here is a part of the code where I call useAxios hook.

const {axiosData:data1} = useAxios('request1','');
const {axiosData:data2} = useAxios('request2','querystring1');
const {axiosData:data3} = useAxios('request3','querystring2');

The problem I am trying to solve is how to wait for all the requests to finish, so it is for sure that all the data are ready.

I know about the axios.all and would like to use something like that, but with usage of the reusable code like with useAxios.

Side note: there are many useAxios calls through the app, not just the one case I explain here. That is the reason I am trying to reuse it instead using one axios.all

CodePudding user response:

Obviously you could do something as simple as

if (data1 && data2 && data3) {
  // do something
}

Since that code will run any time one of those stat variables changes. Or you could put them all as dependencies on a useEffect().

I suspect folks might steer you toward using a state machine if things are getting complicated. See useReducer()

CodePudding user response:

Don't destructure the axiosData property from each object returned by the hook. That way, you can inspect the axiosLoading property on every dataN value to make a determination of whether or not they're all done, like this:

const data1 = useAxios('request1','');
const data2 = useAxios('request2','querystring1');
const data3 = useAxios('request3','querystring2');

const done = [data1, data2, data3].every(({axiosLoading}) => !axiosLoading);
if (done) {
  // they're all done loading
}
else {
  // at least one is still loading
}
  •  Tags:  
  • Related