Search code examples
reactjsredux-toolkitrtk-query

Using RTK query with modules structure and calling multiple apis in one component overrides the previous previous url and values


I am using RTK query with a modular structure. So I don't need to write endpoints per url. The problem is if I call two api call in one components the recent call with override the previous one.

JobformContainer.jsx

import clients from '../../redux/modules/clients';
import yupSchemaService from '../../services/yupSchemaService';
import dataService from '../../services/dataService';
import { fetchAutoCompleteData } from '../../services/autoCompleteService';
import jobs from '../../redux/modules/jobs';
  const {
    data: jobData,
    error: jobError,
    isFetching: jobLoading,
  } = jobs.list().useJobDetailQuery({
    params: { id: params.jobId },
    extendedPath: apiUrls.getJob(),
    skip: !params.jobId,
  });

  const {
    data: clientsList,
    isFetching: isLoadingClient,
    error: errorClient,
    isSuccess: successClient,
  } = clients
    .list()
    .useListQuery(
      { params: '', extendedPath: apiUrls.getClientListing() },
      { refetchOnMountOrArgChange: true },
    );

  const [createJob, createJobData] = jobs.form().useCreateMutation();

Client.js for clients api calls

import form from '../apiService/form';
import list from '../apiService/list';
import destroy from '../apiService/destroy';

const clients = {};
clients.list = () => list('/rest/clients', 'clients');
clients.form = () => form('/rest/clients', 'clients');
clients.delete = () => destroy('/rest/clients/delete', 'clients');

export default clients;

jobs.js for jobs module api calls

import _ from 'lodash';
import form from '../apiService/form';
import list from '../apiService/list';

const jobs = {};
jobs.list = () => list('/rest/jobs', 'job');
jobs.form = () => form('/rest/jobs', 'job');

export default jobs;

list.js is code splitting of rtk where I inject endpoints

import { authHeader } from '../../constants/authenticationHeader';
import { baseSliceWithTags } from '../baseSlice';

const list = (path, module) => {
  const listApi = baseSliceWithTags.injectEndpoints({
    endpoints: (builder) => {
      return {
        list: builder.query({
          query: (payload) => {
            return {
              url: path + (payload?.extendedPath || ''),
              method: 'get',
              csrf: authHeader(),
              params: payload?.params,
            };
          },
          providesTags: [module],
        }),
        detail: builder.query({
          query: (payload) => ({
            url: path + (payload?.extendedPath || ''),
            method: 'get',
            csrf: authHeader(),
            params: payload?.params,
          }),
          providesTags: [module],

          keepUnusedDataFor: 0,
        }),
      };
    },
    overrideExisting: true,
  });
  return listApi;
};
export default list;

Network calls

As in network all calls are /clients module call even though I have called the jobs module but it gets called with clients parameters.


Solution

  • Your endpoints need unique names for that api, so clientList and formList.

    To be clear: you are injecting into the same api. This is not giving you new hooks every time, if you inject a new endpoint with the same name, it overrides the internal config and returns the same hook.

    As you are doing it, they overwrite each other. That is also why you are getting error messages unless you activate overrideExisting: true.

    Essentially, RTK Query was warning you that you should not do it, but you did it anyways ;)