I am integrating firebase in a slice. I have the extra reducers for loginAsync
. If I enter incorrect details, it says pending, then success. It also doesn't catch the error thrown by firebase.
export const loginAsync = createAsyncThunk('user/login', async (credentials: ILoginCredentials) => {
signInWithEmailAndPassword(
auth,
credentials.email,
credentials.password
)
.then((userCredential) => {
const user = userCredential.user
return user
})
.catch((error) => {
console.log('failed')
return isRejectedWithValue(error.message)
})
})
This is the builders in my slice
extraReducers: (builder) => {
builder.addCase(loginAsync.pending, (state, action) => {
console.log('pending')
state.loading = 'pending'
})
builder.addCase(loginAsync.fulfilled, (state, action) => {
state.user = action.payload
state.loading = 'succeeded'
console.log(state.loading)
})
builder.addCase(loginAsync.rejected, (state, action) => {
state.loginError = action.error.message
state.loading = 'failed'
console.log('failed')
})
How do I correctly catch the error and set it in the slice state? Why is the rejected signin going into the fulfilled builder?
The issue here is that that loginAsync
action isn't actually returning a value, so the implicitly returned Promise is returned and since there were no uncaught errors or Promise rejections the function automatically resolves.
Either return the Promise chain so the resolved value or rejectWithValue
is returned:
export const loginAsync = createAsyncThunk(
'user/login',
(credentials: ILoginCredentials, { rejectWithValue }) => {
return signInWithEmailAndPassword( // <-- return Promise chain!
auth,
credentials.email,
credentials.password
)
.then((userCredential) => {
return userCredential.user;
})
.catch((error) => {
console.log('failed');
return rejectWithValue(error.message);
})
});
Or convert the logic to use async/await
/try/catch
instead of the Promise chain:
export const loginAsync = createAsyncThunk(
'user/login',
async (credentials: ILoginCredentials, { rejectWithValue }) => {
try {
const { user } = await signInWithEmailAndPassword(
auth,
credentials.email,
credentials.password
);
return user;
} catch(error) {
console.log('failed');
return rejectWithValue(error.message);
}
});