skip to Main Content

I wanted to split the API into two parts, but the provided tag endpoint didn’t refetch itself, when the invalidatesTag endpoint at the other part was called.
BaseApi:

import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const baseApi = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: `${import.meta.env.VITE_SERVER}` }),
  tagTypes: ["Cart", "Shopping", "Product"],
  endpoints: () => ({}),
});

CartApi:

import { baseApi } from "../BaseApi/baseApi";
type CartItemType = {
  product_id?: string;
  quantity?: number;
};
type CartType = {
  _id: string;
} & CartItemType;
type CartResponse = {
  message: string;
  data: CartType;
};

export const cartApi = baseApi.injectEndpoints({
  endpoints: (builder) => ({
    getCartByProDuctId: builder.query<CartResponse, string>({
      query: (id: string) => `cart-item/${id}`,
      providesTags: ["Cart"],
    }),
    createCart: builder.mutation<CartResponse, CartItemType>({
      query: (data: CartItemType) => ({
        url: "/cart-item/create",
        method: "PUT",
        body: data,
      }),
    }),
    updateCart: builder.mutation<CartResponse, CartItemType>({
      query: (data: CartItemType) => ({
        url: "/cart-item/update",
        method: "PATCH",
        body: data,
        invalidatesTags: ["Shopping"],
      }),
    }),
    deleteCart: builder.mutation<CartResponse, CartItemType>({
      query: (data: CartItemType) => ({
        url: "/cart-item/delete",
        method: "DELETE",
        body: data,
      }),
    }),
  }),
});
export const {
  useGetCartByProDuctIdQuery,
  useCreateCartMutation,
  useUpdateCartMutation,
  useDeleteCartMutation,
} = cartApi;

ShoppingApi:

import { baseApi } from "../BaseApi/baseApi";
import type { ProductType } from "../ProductReducer/ProductApi";
type cart_item = {
  product_id: ProductType;
  quantity: number;
};
type ShoppingSessionType = {
  cart_items: cart_item[];
  user_id?: string;
};
type shoppingType = {
  id: string;
  CartItemId: string;
};
export const shoppingApi = baseApi.injectEndpoints({
  endpoints: (builder) => ({
    getShoppingSession: builder.query<ShoppingSessionType, string>({
      query: (id: string) => `shopping/${id}`,
      providesTags: ["Shopping"],
    }),

    updateCartItem: builder.mutation<ShoppingSessionType, shoppingType>({
      query: ({ id, CartItemId }: shoppingType) => ({
        url: `shopping/update-cart-item/${id}`,
        method: "PATCH",
        body: { CartItemId },
      }),
      invalidatesTags: ["Shopping"],
    }),
    updateDeleteCartItem: builder.mutation<ShoppingSessionType, shoppingType>({
      query: ({ id, CartItemId }: shoppingType) => ({
        url: `shopping/update-delete/${id}`,
        method: "PATCH",
        body: { CartItemId },
      }),
    }),
  }),
});
export const {
  useGetShoppingSessionQuery,
  useUpdateCartItemMutation,
  useUpdateDeleteCartItemMutation,
} = shoppingApi;

My store setup:

import { configureStore } from "@reduxjs/toolkit";
import AuthReducer from "../api/AuthReducer/AuthReduce";
import { AuthMiddleware } from "../middleware/AuthMiddleware";
import { combineReducers } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/dist/query";
import { userApi } from "../api/UserApi/UserApi";
import { productApi } from "../api/ProductReducer/ProductApi";
import { paymentUserApi } from "../api/UserApi/UserPaymentApi";
import { shoppingApi } from "../api/ShoppingSessionApi/ShoppingSessionApi";
import { cartApi } from "../api/CartReducer/CartApi";
import { baseApi } from "../api/BaseApi/baseApi";
import { ErrorLogger } from "../middleware/ErrorLogger";
const rootReducer = combineReducers({
  auth: AuthReducer,
  [userApi.reducerPath]: userApi.reducer,
  [productApi.reducerPath]: productApi.reducer,
  [paymentUserApi.reducerPath]: paymentUserApi.reducer,
  [baseApi.reducerPath]: baseApi.reducer,
  [cartApi.reducerPath]: cartApi.reducer,
  [shoppingApi.reducerPath]: shoppingApi.reducer,
});
export const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) => [
    ...getDefaultMiddleware(),
    userApi.middleware,
    productApi.middleware,
    paymentUserApi.middleware,
    baseApi.middleware,
    cartApi.middleware,
    shoppingApi.middleware,
    AuthMiddleware,
    ErrorLogger,
  ],
});
setupListeners(store.dispatch);
export type RootState = ReturnType<typeof rootReducer>;
export type AppDispatch = typeof store.dispatch;

When I call the endpoint updateCart, the endpoint getShoppingSession should refetch. Thank you for your help

2

Answers


  1. Chosen as BEST ANSWER

    I've found my own solution for this. the line invalidatesTag should move out of the query.

    updateCart: builder.mutation<CartResponse, CartItemType>({
          query: (data: CartItemType) => ({
            url: "/cart-item/update",
            method: "PATCH",
            body: data,
            invalidatesTags: ["Shopping"],
          }),
        }),
    

    should like:

    updateCart: builder.mutation<CartResponse, CartItemType>({
          query: (data: CartItemType) => ({
            url: "/cart-item/update",
            method: "PATCH",
            body: data,
          }),
            invalidatesTags: ["Shopping"],
        }),
    

  2. Only add your baseApi to your store – this is all the same api, just with more endpoints every time. You are essentially adding the same middleware 6 times.

    export const store = configureStore({
      reducer: {
        auth: AuthReducer,
        [baseApi.reducerPath]: userApi.reducer,
      },
      middleware: (getDefaultMiddleware) => 
        getDefaultMiddleware()
        .concat(baseApi.middleware)
        .concat(AuthMiddleware)
        .concat(ErrorLogger)
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search