Reputation: 465
On my api I have two mutations and strangely, one of them does trigger the refetch but the other doesn't and I have no clue why. Both mutations make their networks calls and changes are reflected in the server.
Here's my api definition.
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/dist/query/react";
import Sample from "core/types/Sample";
import getApiURL from "core/utils/getApiURL";
export const lithologyApi = createApi({
baseQuery: fetchBaseQuery({ baseUrl: getApiURL() }),
tagTypes: ["Samples"],
endpoints: build => ({
addSample: build.mutation<Sample, Sample>({
query: sample => ({
url: `lithology/add-sample`,
method: "POST",
body: sample,
}),
invalidatesTags: ["Samples"],
}),
getSamples: build.query<Sample[], void>({
query: () => "lithology/get-samples",
providesTags: ["Samples"],
}),
deleteSample: build.mutation<void, number>({
query: id => ({ url: `lithology/delete-sample/${id}`, method: "DELETE" }),
invalidatesTags: ["Samples"],
}),
}),
});
export const {
useAddSampleMutation,
useGetSamplesQuery,
useDeleteSampleMutation,
} = lithologyApi;
I don't know if it's relevant but the mutation that succesfully invalidates (addSample
) it's in a different component, while the one that doesn't (deleteSample
) it's in the same (I've already tried moving it to another component and it didn't work anyways).
Upvotes: 7
Views: 10417
Reputation: 472
Try adding the next function to the file and replace the providedTags
in getSamples
query function.
const providesTags = (result: ReportPinsResponse | undefined) => {
if (result && result.items) {
const { items } = result;
return [...items.map(({ id }) => ({ type: CACHE_TAGS.Samples, id }))];
}
return [CACHE_TAGS.Samples];
};
And then your query mutation will look like:
deleteSample: builder.mutation<void, number>({
query: (id) => ({
url: `lithology/delete-sample/${id}`,
method: 'DELETE',
}),
invalidatesTags: (_, __, id) => [{ type: CACHE_TAGS.Samples, id }],
}),
enum CACHE_TAGS {
Samples = 'Samples',
}
Upvotes: 0
Reputation: 6128
In my case it was related to not adding the middleware to configureStore
.
export const lithologyApi = createApi({
// ....
});
const store = configureStore({
// ....
// Adding the api middleware enables caching, invalidation, polling,
// and other useful features of `rtk-query`.
middleware: [
lithologyApi.middleware,
],
});
Upvotes: 2
Reputation: 44136
So, just to give an answer here so that someone else can maybe use it:
I assume that your deleteSample
endpoint was giving an empty response. Per default, fetchBaseQuery
's responseHandler
is set to json
, so it tries to JSON.parse
an empty string - and crashes with an unhandled error.
Uncaught SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
Now, invalidateTags
is only called on success and for handled errors, but not in the case of an unhandled error, since that would lead to all kinds of inpredictable behaviour in case your invalidateTags
was not an array, but a function.
Long story short: In your request, set responseHandler
to text
or a custom function.
Also, always read errors - when you read that error above getting back from your hook, it should already become pretty obvious :)
Upvotes: 2