I'm following the example in the official doc Matching Utilities, and trying to use isAllOf
to update state when all the API calls have been successfully made. All the parameters will be created by createAsyncThunk
, i.e.:
export const fetchCart = createAsyncThunk(
"api/fetchCart",
async (payload, { rejectWithValue }) => {
try {
// Replace with your actual API call logic
const response = await fetch("https://dummyjson.com/cart");
const data = await response.json();
return data;
} catch (error) {
return rejectWithValue(error.response.data);
}
},
);
and the way I'm calling it is similar to:
// src/store/pageStatusSlice.js
import { createSlice, isAllOf, isAnyOf, isRejected } from "@reduxjs/toolkit";
import { fetchCart } from "./cartSlice";
import { fetchProduct } from "./productSlice"; // Import your thunks
const pageStatusSlice = createSlice({
name: "pageStatus",
initialState: {
isLoading: false,
success: false,
error: false,
},
extraReducers: (builder) => {
builder
.addMatcher(isAllOf(fetchProduct.pending, fetchCart.pending), (state) => {
state.isLoading = true;
})
.addMatcher(
isAllOf(fetchCart.fulfilled, fetchProduct.fulfilled),
(state, action) => {
state.isLoading = false;
state.success = true;
},
)
.addMatcher(
isAnyOf(fetchCart.rejected, fetchProduct.rejected),
(state, action) => {
console.log(action);
state.error = true;
},
);
},
});
export default pageStatusSlice.reducer;
The rejection case is working, but not with the pending and fulfilled case, seems like both pending and fulfilled cases are not triggered.
When there is only 1 parameter passed in the isAllOf
, it works fine.
I checked Error when using Redux toolkit's isAnyOf - TypeError: matcher is not a function, in the code snippet provided in this question, it seems like it's using the matching utilities in the same way:
builder
.addMatcher(
isAnyOf(getAllData.fulfilled, addQuestion.fulfilled, getQuestion.fullfilled, updateQuestion.fulfilled),
(state) => {
state.connectionError = null
}
)
The answer from the question above mentioned he accidently put .fulfilled
at the end of the action and it was causing error, but in the official doc seems like using .fulfilled
is allowed:
import { createReducer, isAllOf } from '@reduxjs/toolkit'
import {
isSpecialAndInterestingThunk,
initialState,
isSpecial,
isInteresting,
} from '@virtual/matchers' // This is a fake pkg that provides the types shown above
const loadingReducer = createReducer(initialState, (builder) => {
builder
.addMatcher(
isAllOf(isSpecialAndInterestingThunk.fulfilled, isSpecial),
(state, action) => {
state.isSpecial = true
}
)
.addMatcher(
isAllOf(isSpecialAndInterestingThunk.fulfilled, isInteresting),
(state, action) => {
state.isInteresting = true
}
)
})
I have also created a code sandbox with a simple example: https://codesandbox.io/p/sandbox/admiring-dewdney-crdqdz?file=%2Fsrc%2Findex.js
isAllOf
means "is all of these at the same time".
So isAllOf(fetchProduct.pending, fetchCart.pending)
means "it's an action for a pending fetchProduct
thunk and a pending fetchCart
thunk at the same time".
Which is literally impossible.
You probably want to use isAnyOf
which means "is one of these things" instead.