I'm currently encountering an issue with Redux where I'm unable to retrieve data from the store using the selectAll selector when using named parameters in my query function.
I can add a new selector that filters the data retrieved from GET query by ownerId. However, I do not want to GET all the records with different ownerIds.
To be able to get records by ownerId from DB, I changed the query in the recordController on server-side. Now it returns only records with specific ownerId.
const getRecordsByOwner = async (req, res) => {
const {ownerId} = req.query
const records = await Record.find({ ownerId: ownerId }).lean();
if (!records?.length) {
return res.status(404).json({ message: 'No record found' });
}
res.json(records);
}
Then, I added the ownerId parameter in the Redux slice (recordsApiSlice) to fetch data by ownerId. The recordsApiSlice that I implement:
import {
createSelector,
createEntityAdapter
} from "@reduxjs/toolkit";
import { apiSlice } from "../../app/api/apiSlice"
const recordsAdapter = createEntityAdapter({})
const initialState = recordsAdapter.getInitialState()
export const recordsApiSlice = apiSlice.injectEndpoints({
endpoints: builder => ({
getRecordsByOwnerId: builder.query({
query: (ownerId) => `/records?ownerId=${ownerId}`,
validateStatus: (response, result) => {
return response.status === 200 && !result.isError
},
transformResponse: responseData => {
const retrievedRecords = responseData.map(record => {
record.id = record._id
return record
});
return recordsAdapter.setAll(initialState, retrievedRecords )
},
providesTags: (result, error, arg) => {
if (result?.ids) {
return [
{ type: 'Record', id: 'LIST' },
...result.ids.map(id => ({ type: 'Record', id }))
]
} else return [{ type: 'Record', id: 'LIST' }]
}
}),
}),
})
export const {
useGetRecordsByOwnerId
} = recordsApiSlice
export const selectRecordsResult = recordsApiSlice.endpoints.getRecordsByOwnerId.select()
const selectRecordsData = createSelector(
selectRecordsResult,
recordsResult => recordsResult.data
)
export const {
selectAll: selectAllRecords,
selectById: selectRecordsById,
selectIds: selectRecordIds
} = recordsAdapter.getSelectors(state => selectRecordsData(state) ?? initialState)
Then, I used the queries in the React component:
useGetRecordsByOwnerQuery(ownerId)
const records = useSelector(selectAllRecords);
The API response is successfully received, processed, and stored in the Redux store. I verified it in Redux DevTools, Network activity in Dev Tools, and placed several console.logs to see how data is processed along the request and response. However, the records variable in the React component is set to an empty array. I cannot select the data from fullfilled query in the store.
Here record is not defined. It should probably be:
Once the data is correctly in the store and if the selectors are set up correctly,
useSelector(selectAllRecords)should be able to pick up the data.