Search code examples
javascriptreactjsreact-reduxredux-toolkitrtk-query

Auto-refetch a mutation by invalidating its tag from another mutation


Can I auto-refetch getEmployees mutation by invalidating its tag from another mutation called deleteEmployee in the code below?

import { createApi } from '@reduxjs/toolkit/query/react'
import customFetchBase from './customFetchBase.js'

export const publicApi = createApi({
  reducerPath: 'publicApi',
  baseQuery: customFetchBase,
  tagTypes: ['employees'],
  endpoints: builder => ({
    getEmployees: builder.mutation({
      query: ({
        formData = "defaultHashedDataString",
        salt = "xyz",
        pageIndex = 1
      }) => ({
        url: '/Hafez/Employee/Data',
        method: 'POST',
        body: {
          RequestVerificationToken: salt,
          FormData: formData,
          currentPage: pageIndex + 1
        }
      }),
      providesTags: ['employees']
    }),
    deleteEmployee: builder.mutation({
      query: ({ formData, salt }) => ({
        url: '/Hafez/Employee/Delete',
        method: 'POST',
        body: { RequestVerificationToken: salt, FormData: formData }
      }),
      invalidatesTags: ['employees']
    })
  })
})

export const { useGetEmployeesMutation, useDeleteEmployeeMutation } = publicApi

Now when I call deleteEmployee mutation the getEmployees mutation does not run.

I know that I should use a GET request for getting data from server but for some security it can't be changed.


Solution

  • Queries provide tags, mutations invalidate them. It seems to me that getEmployees should be a query instead of a mutation. When the deleteEmployee endpoint is called and successfully invalidates the "employees" tag, then any current subscribers to the now useGetEmployeesQuery hook will automatically trigger the getEmployees query to refetch.

    export const publicApi = createApi({
      reducerPath: 'publicApi',
      baseQuery: customFetchBase,
      tagTypes: ['employees'],
      endpoints: builder => ({
        getEmployees: builder.query({ // <-- update to query
          query: ({
            formData = "defaultHashedDataString",
            salt = "xyz",
            pageIndex = 1
          }) => ({
            url: '/Hafez/Employee/Data',
            method: 'POST',
            body: {
              RequestVerificationToken: salt,
              FormData: formData,
              currentPage: pageIndex + 1
            }
          }),
          providesTags: ['employees']
        }),
        deleteEmployee: builder.mutation({
          query: ({ formData, salt }) => ({
            url: '/Hafez/Employee/Delete',
            method: 'POST',
            body: { RequestVerificationToken: salt, FormData: formData }
          }),
          invalidatesTags: ['employees']
        })
      })
    });
    
    export const {
      useGetEmployeesQuery, // <-- updated hook name
      useDeleteEmployeeMutation
    } = publicApi;
    

    Please note that the endpoints are either queries or mutations and that this is completely independent from the request method, e.g. GET, POST, PUT, etc.