I'm building a project using Redux Toolkit with RTK Query and I am trying to get some entries from an API. I'm using the normalized data approach with the createEntityAdapter
and because in a certain component I need the data as an array I have ended up using selectors. Now my issue is that since I added filters as a parameter for my query, my selector stopped working.
I have studied similar questions here, like: How to use RTK query selector with an argument?, but I'm just too dumb to understand what I am supposed to modify. I have tried to make sense of the RTK Query Docs but I couldn't.
From the question above I got that my selector needs to also have the params in order to know what to select exactly and that it is not a recommended pattern but I couldn't understand how to make it work.
My entry slice:
import { createSelector, createEntityAdapter } from '@reduxjs/toolkit'
import { apiSlice } from './apiSlice'
const entryAdapter = createEntityAdapter()
const initialState = entryAdapter.getInitialState({
ids: [],
entities: {},
})
export const entryApiSlice = apiSlice.injectEndpoints({
endpoints: (builder) => ({
initialState,
getEntry: builder.query({
query: (filters) => ({
url: '/history',
params: filters,
}),
transformResponse: (responseData) => {
return entryAdapter.setAll(initialState, responseData)
},
providesTags: (result, error, arg) => [
{ type: 'Entry', id: 'LIST' },
...result.ids.map((id) => ({ type: 'Entry', id })),
],
}),
addEntry: builder.mutation({
query: (data) => ({
url: '/history/new',
method: 'POST',
body: data,
}),
invalidatesTags: [{ type: 'Entry', id: 'LIST' }],
}),
updateEntry: builder.mutation({
query: (initialEntry) => ({
url: `/history/${initialEntry.Id}`,
method: 'PUT',
body: {
...initialEntry,
date: new Date().toISOString(),
},
}),
invalidatesTags: (result, error, arg) => [{ type: 'Entry', id: arg.id }],
}),
deleteEntry: builder.mutation({
query: ({ id }) => ({
url: `/history/${id}`,
method: 'DELETE',
body: { id },
}),
invalidatesTags: (result, error, arg) => [{ type: 'Entry', id: arg.id }],
}),
}),
})
export const {
useGetEntryQuery,
useAddEntryMutation,
useUpdateEntryMutation,
useDeleteEntryMutation,
} = entryApiSlice
export const selectEntryResult = (state, params) =>
entryApiSlice.endpoints.getEntry.select(params)(state).data
const entrySelectors = entryAdapter.getSelectors(
(state) => selectEntryResult(state) ?? initialState
)
export const selectEntry = entrySelectors.selectAll
And I'm using it in a Entries
component like this
const {
data: entriesData = [],
refetch,
isLoading,
isSuccess,
isError,
error,
} = useGetEntryQuery(filters)
const entries = useSelector(selectEntry)
Note: If I remove the filters
from the get query everything works as before (as expected of course).
Disclaimer: I do not know what I am doing exactly, I have read the docs and I'm trying to figure it out, so any feedback is very much appreciated.
Thank You!