RTK Query tags not invalidating/ refetching

Viewed 2215

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

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.

Related