Search code examples
javascriptreactjsrtk-query

How can I make API calls conditionally using Redux Toolkit query/createApi?


I am only using RTK to make API calls. Not using for any state management stuff like using Slices or Redux Thunk etc. I don't have a clear understanding of those yet... (just a full disclosure)

I have tried this:

export const gymApi = createApi({
  reducerPath: 'gymApi',
  baseQuery: fetchBaseQuery({ baseUrl }),
  endpoints: (builder) => ({
    getAllWorkouts: builder.query({
      query: () => makeApiCall(`/exercises`),
    }),
    getWorkoutByBodyPart: builder.query({
      query: (bodyPart) => {
        console.log('BodyPart in GymApi:', bodyPart);
        if (bodyPart !== 'all') {
          return makeApiCall(`/exercises/bodyPart/${bodyPart}`);
        } else {
          return null;
        }
      },
    })
});

And tried this:

getWorkoutByBodyPart: builder.query({
      query: (bodyPart) => {
        console.log('BodyPart in GymApi:', bodyPart);
        if (bodyPart !== 'all') {
          return makeApiCall(`/exercises/bodyPart/${bodyPart}`);
        } else {
          return Promise.resolve({ data: [] }); // or Promise.resolve({}); 
        }
      },
    })

with no luck. I'm calling the hooks from the home page like this:

const Exercises = ({ exercises, setExercises, bodyPart }) => {
  // THE FOLLOWING WORKS. ONLY USGING STATIC DATA DUE TO API HARD LIMITS
  const { data: exercisesData, isFetching: isFetchingAllWorkouts } =
    useGetAllWorkoutsQuery();

  const { data: exercisesDataByCategory, isFetching: isFetchingByCategory } =
    useGetWorkoutByBodyPartQuery(bodyPart);

  useEffect(() => {
    if (exercisesData && exercisesDataByCategory) {
      if (bodyPart === 'all') {
        setExercises(exercisesData);
      } else {
        setExercises(exercisesDataByCategory);
      }
    }
  }, [exercisesData, bodyPart, isFetchingAllWorkouts, isFetchingByCategory]);

It is working but with every refresh, I get a Warning: "Category not found ..." from the API ... basically, there is no endpoint called "all" in the ExerciseDB API (in RapidAPIs). So every time an "all" is passed as a Category, it gives me a 401. Now the App works fine. I was just wondering if there is a cleaner way to do this. I mean, I don't wanna make a call to the API when the Category is "all".

I must say that I'm new to this. Trying to get out of using Fetch all the time and take advantage of RTK caching. Any help in the correct direction will be highly appreciated. Thanx in advance.


Solution

  • My issue got resolved by RTK LazyQuery:

    
      const [
        getAllWorkouts,
        { data: exercisesData, isFetching: isFetchingAllWorkouts },
      ] = useLazyGetAllWorkoutsQuery();
    
      const [
        getWorkoutByPart,
        { data: exercisesDataByCategory, isFetching: isFetchingByCategory },
      ] = useLazyGetWorkoutByBodyPartQuery();
    
      useEffect(() => {
           
          if (bodyPart === 'all') {
            getAllWorkouts();
            setExercises(exercisesData);
            
          } else {
            getWorkoutByPart(bodyPart);
            setExercises(exercisesDataByCategory);
            setCurrentPage(1);
          }
         
      }, [exercisesData, bodyPart, isFetchingAllWorkouts, isFetchingByCategory]);