login$ = createEffect(() => {
return this.action$.pipe(
ofType(fromActions.loginStart),
exhaustMap(action => {
return this.authService
.login({
username: action.username,
password: action.password,
})
.pipe(
map(data => {
const user = this.authService.handleLogin(data);
return fromActions.loginSuccess({
roles: user._roles,
token: user._token,
expiration: user._expiration.toString(),
});
}),
catchError(error => {
return of(fromActions.loginFailure({ error: error.message }));
})
);
})
);
});
In the above code snippet the return to loginSuccess reducer works successfully, but same call to reducer loginSuccess doesn't works for below function:
autoAuth$ = createEffect(() => {
return this.action$.pipe(
ofType(fromActions.autoAuthenticate),
map(() => {
const user = this.authService.getAuthDataFromLocalStorage();
if (user && user._expiration && user._expiration > new Date()) {
this.authService.onSuccessfulAuthentication(user._expiration);
return fromActions.loginSuccess({
roles: user._roles,
token: user._token,
expiration: user._expiration.toString(),
});
} else {
return fromActions.loginFailure({ error: 'Login Failed' });
}
})
);
});
Function is being executed successfully, as there is one more effect which is successfully executed by both the snippets.
loginRedirect$ = createEffect(
() => {
return this.action$.pipe(
ofType(loginSuccess),
map(() => {
this.router.navigate(['home']);
})
);
},
{ dispatch: false }
);
}
I am unable to figure out why the reducer is not being called in the second case as action is dispatched in both cases.
Have tried replacing loginSuccess with a different action which does not require any data to be passed , but still the code not able to go to reducer
You should use
switchMapinstead ofmapto preserve the Observable result: