Search code examples
javascriptreduxredux-toolkit

Redux-Toolkit: How to reject a "createAsyncThunk"?


How to reject properly with createAsyncThunk. I have an asynchronous function that checks whether a mail address already exists or not. The response of the function is an empty string if there is no registered mail address and the user object of the registered user if the user exists.

export const checkIfEmailExists = createAsyncThunk(
  "user/checkIfEmailExists",
  async (mail) => {
    const response = await mailExists(mail).promise();
    if (response.user && response.user.length > 0) {
      reject();
    } else {
      resolve();
    }
  }
);

In both cases the data comes back and no error occurs. How do I reject the createAsyncThunk in such a case?


Solution

  • You can use rejectWithValue to handle Thunk Errors.

    E.g.

    import {
      configureStore,
      createAsyncThunk,
      createSlice,
    } from '@reduxjs/toolkit';
    
    function mailExists(mail) {
      return {
        async promise() {
          // return { user: [{ name: 'teresa teng', mail }] };
    
          return { user: [] };
        },
      };
    }
    
    export const checkIfEmailExists = createAsyncThunk(
      'user/checkIfEmailExists',
      async (mail: string, { rejectWithValue }) => {
        const response = await mailExists(mail).promise();
        if (response.user && response.user.length > 0) {
          return response.user[0];
        } else {
          return rejectWithValue('No user found');
        }
      }
    );
    
    const userSlice = createSlice({
      name: 'user',
      initialState: {
        data: {},
        error: null,
      },
      reducers: {},
      extraReducers: (builder) => {
        builder
          .addCase(checkIfEmailExists.fulfilled, (state: any, action) => {
            state.data = action.payload;
          })
          .addCase(checkIfEmailExists.rejected, (state: any, action) => {
            state.error = action.payload;
          });
      },
    });
    
    const store = configureStore({
      reducer: {
        user: userSlice.reducer,
      },
    });
    
    store.dispatch(checkIfEmailExists('[email protected]')).then(() => {
      console.log(store.getState());
    });
    

    Output of the console:

    { user: { data: {}, error: 'No user found' } }