Skip to content

Commit

Permalink
Support null or undefined when invalidateTags is a function
Browse files Browse the repository at this point in the history
pierroberto committed Oct 19, 2024
1 parent 459e4ec commit a9def39
Showing 2 changed files with 32 additions and 4 deletions.
4 changes: 3 additions & 1 deletion packages/toolkit/src/query/endpointDefinitions.ts
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@ import type {
OmitFromUnion,
UnwrapPromise,
} from './tsHelpers'
import { isNotNullish } from './utils'

const resultType = /* @__PURE__ */ Symbol()
const baseQuery = /* @__PURE__ */ Symbol()
@@ -224,7 +225,7 @@ export type GetResultDescriptionFn<
error: ErrorType | undefined,
arg: QueryArg,
meta: MetaType,
) => ReadonlyArray<TagDescription<TagTypes>>
) => ReadonlyArray<TagDescription<TagTypes> | undefined | null>

export type FullTagDescription<TagType> = {
type: TagType
@@ -778,6 +779,7 @@ export function calculateProvidedBy<ResultType, QueryArg, ErrorType, MetaType>(
queryArg,
meta as MetaType,
)
.filter(isNotNullish)
.map(expandTagDescription)
.map(assertTagTypes)
}
32 changes: 29 additions & 3 deletions packages/toolkit/src/query/tests/buildMiddleware.test.tsx
Original file line number Diff line number Diff line change
@@ -25,9 +25,15 @@ const api = createApi({
},
providesTags: ['Bread'],
}),
invalidateFruit: build.mutation({
query: (fruit?: 'Banana' | 'Bread' | null) => ({ url: `invalidate/fruit/${fruit || ''}` }),
invalidatesTags(result, error, arg) {
return [arg]
}
})
}),
})
const { getBanana, getBread } = api.endpoints
const { getBanana, getBread, invalidateFruit } = api.endpoints

const storeRef = setupApiStore(api, {
...actionsReducer,
@@ -91,7 +97,10 @@ it('invalidates tags correctly when null or undefined are provided as tags', asy
})


it.each([{ tags: [undefined, null, 'Bread'] as Parameters<typeof api.util.invalidateTags>['0'] }, { tags: [undefined, null], }, { tags: [] }])('does not invalidate with tags=$tags if no query matches', async ({ tags }) => {
it.each([
{ tags: [undefined, null, 'Bread'] as Parameters<typeof api.util.invalidateTags>['0'] },
{ tags: [undefined, null], }, { tags: [] }]
)('does not invalidate with tags=$tags if no query matches', async ({ tags }) => {
await storeRef.store.dispatch(getBanana.initiate(1))
await storeRef.store.dispatch(api.util.invalidateTags(tags))

@@ -107,4 +116,21 @@ it.each([{ tags: [undefined, null, 'Bread'] as Parameters<typeof api.util.invali

expect(storeRef.store.getState().actions).toMatchSequence(...apiActions)
})


it.each([{ mutationArg: 'Bread' as "Bread" | null | undefined }, { mutationArg: undefined }, { mutationArg: null }])('does not invalidate queries when a mutation with tags=[$mutationArg] runs and does not match anything', async ({ mutationArg }) => {
await storeRef.store.dispatch(getBanana.initiate(1))
await storeRef.store.dispatch(invalidateFruit.initiate(mutationArg))

// Slight pause to let the middleware run and such
await delay(20)

const apiActions = [
api.internalActions.middlewareRegistered.match,
getBanana.matchPending,
getBanana.matchFulfilled,
invalidateFruit.matchPending,
invalidateFruit.matchFulfilled,
]

expect(storeRef.store.getState().actions).toMatchSequence(...apiActions)
})

0 comments on commit a9def39

Please sign in to comment.