Search code examples
javascriptreactjsredux-toolkitrtk-query

The entity passed to the `selectId` implementation returned RTK Query


I used the code example from the official RTK query documentation

https://redux.js.org/tutorials/essentials/part-8-rtk-query-advanced

I am trying to get 30 users from database but for some reason my console is giving me this error for every user: (The entity passed to the selectId implementation returned undefined. You should probably provide your own selectId implementation. The entity that was passed)

Help me understand where (selectId) came from

It's about the getAllUsers request on line 22.

apiSlice.js

import {
  createSelector,
  createEntityAdapter
} from "@reduxjs/toolkit";
import { apiSlice } from '../apiSlice';

const usersAdapter = createEntityAdapter()
const initialState = usersAdapter.getInitialState()

export const extendedApiSlice = apiSlice.injectEndpoints({
  endpoints: (builder) => ({
    getUsers: builder.query({
      query: (pagination) => ({
        url: `/user/pagination/${pagination}`,
      }),
      transformResponse: (response) => {
        return response;
      },
      providesTags: (result, error, id) => [{ type: 'Post', id }],
    }),

    getAllUsers: builder.query({
      query: () => '/user/all',
      transformResponse: (res) => {
        return usersAdapter.setAll(initialState, res)
      },
    }),
  }),
});

export const { useGetUsersQuery, useGetAllUsersQuery } = extendedApiSlice;

export const selectUsersResult = extendedApiSlice.endpoints.getAllUsers.select()

const selectUsersData = createSelector(
  selectUsersResult,
  (usersResult, selectId) => usersResult.data
)

export const {
  selectAll: selectAllUsers,
  selectById: selectUserById,
} = usersAdapter.getSelectors((state) => selectUsersData(state) ?? initialState)

index.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import { App } from './app';
import { store } from './store/store';
import { extendedApiSlice } from './store/friends/friendsApi';
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';

const el = document.getElementById('root');
if (el === null) throw new Error('Root container missing in index.html');

store.dispatch(extendedApiSlice.endpoints.getAllUsers.initiate());

const root = ReactDOM.createRoot(el);

root.render(
  <BrowserRouter>
    <Provider store={store}>
      <App />
    </Provider>
  </BrowserRouter>,
);

Сalling selectAllUsers in the component

const allUsers = useAppSelector(selectAllUsers);
console.log(allUsers);

[console](https://i.sstatic.net/TRZTt.png)

[This solution didn't work for me](https://i.sstatic.net/I4EmW.png)


Solution

  • Entity adapter default expects the entity to have id for unique identification. In your case, as i can see, unique id of the user id named as _id.

    Try the following way of explicitly setting the id:

    const usersAdapter = createEntityAdapter({
      selectId: (user) => user._id,
    });
    

    Hopefully, that should fix the issue.

    Thanks.