Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RTK Query tags not invalidating/ refetching

I'm sure there is something simple and basic that I am missing, but I've looked at all the threads and docs I can find and am not figuring out what I'm not getting here. I just started implementing RTK Query onto a react app and have been going through working out the endpoints one by one.

I have 2 sets of endpoints, clients and contracts. In the db, contracts are subdocs of clients. All the calls are working fine (no errors, all result in fulfilled), and the tags are invalidated in the client endpoints, but not in the contract endpoints. I've tried using a plain basic tag of ['Contract'] and have tried what is in the code below (and with some variations on id's), but all with the same result- having to manually reload the page to refetch.

I've based my use off the examples given here: https://redux-toolkit.js.org/rtk-query/usage/automated-refetching

Again, I'm sure it is something simple I'm not understanding about RTK Query, but I cant spot it.

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const apiSlice = createApi({
    reducerPath: 'api',
    baseQuery: fetchBaseQuery({ baseUrl: 'http://localhost:5000'}),
    tagTypes: ['Client', 'Contract', 'User', 'Visit'],
    endpoints: builder => ({
        getClients:  builder.query({
            query: () => '/clientapi/clients',
        providesTags: ['Client']
        }),
        getClient: builder.query({
            query: clientId => `/clientapi/clients/${clientId}`,
            providesTags: ['Client']
        }),
        addNewClient: builder.mutation({
            query: ({ values }) => ({
                url: '/clientapi/clients',
                method: 'POST',
                body: values
            }),
            invalidatesTags: ['Client']
        }),
        editClient: builder.mutation({
            query: (arg) => {
                const {clientId, values} = arg;
                console.log("clientId: ", clientId, values);
                return {
                url: `/clientapi/clients/${clientId}`,
                method: 'PATCH',
                body: values
                }
            },
            invalidatesTags: ['Client']
        }),
        deleteClient: builder.mutation({
            query: (clientId) => ({
                url: `/clientapi/clients/${clientId}`,
                method: 'DELETE',
                responseHandler: (response) => response.text()
            }),
            invalidatesTags: ['Client']
        }),

        //Contract endpoints
        getContracts:  builder.query({
            
            query: (clientId) => {
            return {
             url:   `/clientapi/clients/${clientId}/contracts`,
            providesTags: //['Contract']
            
            // (result = [], error, arg) => [
            //     'Contract',
            //     ...result.map(({ id }) => ({ type: 'Contract', id}))
            // ]
            
            (result) =>
                result ? [
                    ...result.map(({ id }) => ({ type: 'Contract', id})),
                    { type: 'Contract', id: 'LIST'},
                    ] : [{ type: 'Contract', id: 'LIST'}]
                    
                }
        }
        }),
        getContract: builder.query({
            query: (arg) => {
                const {clientId, contractId} = arg;
                return {
                url: `/clientapi/clients/${clientId}/contracts/${contractId}`,
                method: 'GET'
                }
            },
            providesTags: (result, error, id) => [{ type: 'Contract', id }]
        }),
        addNewContract: builder.mutation({
            query: (arg) => {
                const {clientId, data} = arg;
                return {
                url: `/clientapi/clients/${clientId}/contracts`,
                method: 'POST',
                body: data
                }
            },
            invalidatesTags: [{ type: 'Contract', id: 'LIST' }]
        }),
        editContract: builder.mutation({
            query: (arg) => {
                const {clientId, contractId, data} = arg;
                console.log("clientId: ", clientId, "contractId: ", contractId)
                return {
                url: `/clientapi/clients/${clientId}/contracts/${contractId}`,
                method: 'POST',
                body: data
                }
            },
            invalidatesTags: (result, error, id) => [{ type: 'Contract', id: id}]
        }),
        deleteContract: builder.mutation({
            query: (arg) => {
                const {clientId, contractId} = arg;
                return {
                url: `/clientapi/clients/${clientId}/contracts/${contractId}`,
                method: 'DELETE',
                responseHandler: (response) => response.text()
                }
            },
            invalidatesTags: [{ type: 'Contract', id: 'LIST' }]
        }),

Based on response to other questions along these lines, they indicated the middleware needed to be set in the store, which I did when walking through the tutorial, but maybe I missed something?

import { configureStore } from '@reduxjs/toolkit/query/react';
import { apiSlice } from './apiSlice';

export default configureStore({
    reducer: {
        [apiSlice.reducerPath]: apiSlice.reducer
    },
    middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(apiSlice.middleware)
});

Any help would be greatly appreciated. Thanks

like image 467
Jowz Avatar asked Sep 16 '25 17:09

Jowz


1 Answers

Figured it out, I had put the getContracts providesTags within the same {} of the query, not following. I figured I had overlooked something simple...

getContracts:  builder.query({
            
            query: (clientId) => {
            return {
             url:   `/clientapi/clients/${clientId}/contracts`,
            providesTags: //['Contract']
            
            // (result = [], error, arg) => [
            //     'Contract',
            //     ...result.map(({ id }) => ({ type: 'Contract', id}))
            // ]
            
            (result) =>
                result ? [
                    ...result.map(({ id }) => ({ type: 'Contract', id})),
                    { type: 'Contract', id: 'LIST'},
                    ] : [{ type: 'Contract', id: 'LIST'}]
                    
                }
        }
        }),

changed to:

getContracts:  builder.query({
            
            query: (clientId) => {
            return {
             url:   `/clientapi/clients/${clientId}/contracts`,
            }
        },
         providesTags: //['Contract']
            
            // (result = [], error, arg) => [
            //     'Contract',
            //     ...result.map(({ id }) => ({ type: 'Contract', id}))
            // ]
            
            (result) =>
                result ? [
                    ...result.map(({ id }) => ({ type: 'Contract', id})),
                    { type: 'Contract', id: 'LIST'},
                    ] : [{ type: 'Contract', id: 'LIST'}]
                    
        }),

Thanks @phry, just needed to figure out why the tag wasnt being recognized.

like image 65
Jowz Avatar answered Sep 19 '25 08:09

Jowz