Reputation: 5598
This error occurred when I connect actions to extraReducers My code is
export const fetchCountries = createAsyncThunk(
`country`,
async (organizationId: string) => {
export const saveCountry = createAsyncThunk(
`country`,
async ({ } => {})
const regions = createSlice({
name,
initialState,
reducers: {},
extraReducers: builder => {
builder.addCase(fetchCountries.pending, isFetching);
builder.addCase(fetchCountries.rejected, error);
builder.addCase(fetchCountries.fulfilled, (state, action) => {});
builder.addCase(saveCountry.pending, isFetching);
builder.addCase(saveCountry.rejected, error);
builder.addCase(saveCountry.fulfilled, (state, {payload}) => {});
and if I run I get this error:
Error: addCase cannot be called with two reducers for the same action type
Upvotes: 26
Views: 24115
Reputation: 19
In my case, I was facing this error because of using same action names of asyncThunk. ("orders/fetchOrders") in both functions
First I will show the mistake I was doing is following, check the action names. Both are same mistakenly.
export const fetchOrders = createAsyncThunk("orders/fetchOrders", async () => {
try {
const querySnapshot = await getDocs(
query(collection(db, "orders"), orderBy("createdAt", "desc"))
);
const orders = querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
console.log(orders);
return orders;
} catch (error) {
return Promise.reject(error);
}
});
export const updateOrderStatus = createAsyncThunk(
"orders/fetchOrders",
async ({ orderId, newStatus }) => {
try {
console.log(orderId, newStatus);
const orderRef = doc(db, "orders", orderId);
await updateDoc(orderRef, {
status: newStatus,
updatedAt: Timestamp.now().toDate(),
});
toast.success("Order status updated successfully");
} catch (error) {
toast.error(error.message);
}
}
);
Just keep the action names different
export const fetchOrders = createAsyncThunk("orders/fetchOrders", async () => {
try {
const querySnapshot = await getDocs(
query(collection(db, "orders"), orderBy("createdAt", "desc"))
);
const orders = querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
console.log(orders);
return orders;
} catch (error) {
return Promise.reject(error);
}
});
export const updateOrderStatus = createAsyncThunk(
"orders/updateOrderStatus",
async ({ orderId, newStatus }) => {
try {
console.log(orderId, newStatus);
const orderRef = doc(db, "orders", orderId);
await updateDoc(orderRef, {
status: newStatus,
updatedAt: Timestamp.now().toDate(),
});
toast.success("Order status updated successfully");
} catch (error) {
toast.error(error.message);
}
}
);
Upvotes: 0
Reputation: 13
i had the same problem,have a look below:
//api to get data customers
export const getCustomers = createAsyncThunk('/api/users/customers',async() =>{
...
});
//api to add customer
export const addCustomer = createAsyncThunk<User,{ user: User, token: string }>('/api/users/add_customer', async ({ user, token }) => {
...
});
i got the problem cuz i wrote this path /api/users/customers in frist and second asyncthunk, to solve it ,just need to rename it, in my case, first i didn't change it /api/users/customers and second /api/users/add_customer
Upvotes: 0
Reputation: 139
You are having this error because you are attempting to add multiple asyncthunks with the same typePrefix ie the first argument in the createAsyncthunk. Each asyncthunk must have a unique typePrefix. To resolve this you simply create a unique typePrefix for each createAsyncthunk
export const fetchCountries = createAsyncThunk(
`fetch-country`,
async (organizationId: string) => {
export const saveCountry = createAsyncThunk(
`save-country`,
async ({ } => {})
You can also have the same error message when you try to add multiple reducers for the same action type using the addCase function ie
const regions = createSlice({
name,
initialState,
reducers: {},
extraReducers: builder => {
builder.addCase(fetchCountries.pending, isFetching);
builder.addCase(fetchCountries.rejected, error);
builder.addCase(fetchCountries.fulfilled, (state, action) => {});
builder.addCase(fetchCountries.fulfilled, (state, action) => {});
builder.addCase(saveCountry.pending, isFetching);
builder.addCase(saveCountry.rejected, error);
builder.addCase(saveCountry.fulfilled, (state, {payload}) => {});
Upvotes: 0
Reputation: 954
If your createAsnyncThunk is using the same typePrefix like
const updateEventsCal = createAsyncThunk(
EVENTS_CAL_UPDATE, // using an existing typePrefix say EVENTS_CAL_ADD
async (data) => {
}
This will throw the same error.
Upvotes: 2
Reputation: 46
make it this way
const {pending,fulfilled,rejected} = fetchCountries
builder.addCase(pending, isFetching);
builder.addCase(rejected, error);
builder.addCase(fulfilled, (state, action) => {});
Upvotes: 0
Reputation: 164
In my case, the same error message was show, but it was a different mistake:
.addCase(setAddress.pending, (state, action) => {
state.setAddressStatus = 'Pending';
})
.addCase(setAddress.fulfilled, (state, action) => {
state.setAddressStatus = 'Fulfilled';
})
.addCase(setAddress.fulfilled, (state, action) => { // I repeated fulfilled
state.getAddressesStatus = 'Rejected';
console.error(action.error);
})
It took me some minutes to find the problem, may help someone.
Upvotes: 6
Reputation: 5598
This happens because in my actions there is few AsyncThunks actions with the same typePrefix.
So it must have different names:
export const fetchCountries = createAsyncThunk(
`getCountry`, //<------ this first argument (name) must be unique
async (organizationId: string) => {
export const saveCountry = createAsyncThunk(
`postCountry`,
async ({ } => {})
Upvotes: 70
Reputation: 71
On CreateAsycThunk you have mentioned both the string of the same name it should be like this
export const fetchCountries = createAsyncThunk(
`country`,
async (organizationId: string) => {
export const saveCountry = createAsyncThunk(
`saveCountry`,
async ({ } => {})
const regions = createSlice({
name,
initialState,
reducers: {},
extraReducers: builder => {
builder.addCase(fetchCountries.pending, isFetching);
builder.addCase(fetchCountries.rejected, error);
builder.addCase(fetchCountries.fulfilled, (state, action) => {});
builder.addCase(saveCountry.pending, isFetching);
builder.addCase(saveCountry.rejected, error);
builder.addCase(saveCountry.fulfilled, (state, {payload}) => {});
Upvotes: 4
Reputation: 91
createasyncthunk has two main parameters, one of type string and the latter callback function which has api and thunk as paramters. You are likely to be pardon if having a single asyncthunk in your slice, which has "" as data, but if you have two or more asyncthunks then checks will be made on each thunk, if two or more of them has similar "" or "identical" names then you will get disturbing error. "createAsyncThunk: Error: addCase cannot be called with two reducers for the same action type"
Upvotes: 2