1

I have a problem with setting my rtk query ApiSlice. So what i want to achieve is to get all reviews of a shop or user. I am passing role so i can check should i look for User or Shop, and id to find the right one. Now what i want is to after that create EntityAdapter and some selectors, so i can easily menage my app. The problem is that i dont know how to pass values of id and role to this line of code and after that one : export const selectReviewsResult = reviewsApiSlice.endpoints.getReviews.select();

My code for now:

import { createSelector, createEntityAdapter } from '@reduxjs/toolkit';
import { apiSlice } from '../api/apiSlice';
import { RootState } from '../store';
import { IReview } from '../../components/helpers/Interfaces';

const reviewsAdapter = createEntityAdapter<IReview>({});

const initialState = reviewsAdapter.getInitialState();

export const reviewsApiSlice = apiSlice.injectEndpoints({
  endpoints: (builder) => ({
    getReviews: builder.query<IReview[], { id: string; role: string }>({
      query: ({ id, role }) => ({
        url: '/reviews',
        params: { id, role },
        validateStatus: (response: Response, result: { isError: boolean }) => {
          return response.status === 200 && !result.isError;
        },
        transformResponse: (responseData: { data: IReview[] }) => {
          console.log(responseData.data);
          return responseData.data;
        },
        transformErrorResponse: (response: { status: string | number }) =>
          response.status,
        providesTags: (result: { ids?: string[] }) => {
          if (result?.ids) {
            return [
              { type: 'Review', id: 'LIST' },
              ...result.ids.map((id) => ({ type: 'Review', id })),
            ];
          } else return [{ type: 'Review', id: 'LIST' }];
        },
      }),
      transformResponse: (responseData: IReview[]) => {
        const loadedReviews = responseData.map((review) => {
          const { _id, ...updatedReview } = review as any;
          updatedReview.id = _id;
          return updatedReview;
        });
        const updatedState = reviewsAdapter.setAll(initialState, loadedReviews);
        return Promise.resolve(
          Object.values(updatedState.entities) as IReview[]
        );
      },
    }),
  }),
});
export const { useGetReviewsQuery } = reviewsApiSlice;

// Returns query resuld object
export const selectReviewsResult =
  reviewsApiSlice.endpoints.getReviews.select();

// Creates memoized selector
const selectReviewsData = createSelector(
  selectReviewsResult,
  (reviewsResult) => {
    if (reviewsResult.data) {
      return {
        ids: reviewsResult.data.map((review) => review.id),
        entities: reviewsResult.data.reduce((entities, review) => {
          return { ...entities, [review.id]: review };
        }, {}),
      };
    }
    return { ids: [], entities: {} };
  }
);

// Define the type of state explicitly
const selectReviews = (state: RootState) =>
  selectReviewsData(state as RootState) ?? initialState;

// getSelectors creates these selectors and we rename them
export const {
  selectAll: selectAllReviews,
  selectById: selectReviewsById,
  selectIds: selectReviewIds,
} = reviewsAdapter.getSelectors(selectReviews);

0 Answers0