Does the Angular router have any restrictions to be used inside an NgRx effect?
I just started learning NgRx and I have the following code:
@Effect() public authenticate$ = this.actions$
.ofType(authenticationActions.AUTHENTICATE)
.switchMap((action: AuthenticateAction) => this.authenticationService.authenticate(action.payload)
.map((data: TokenData) => {
const user: User = {
token: data.token,
username: 'dummy',
};
console.log(data);
this.router.navigateByUrl('/');
return new authenticationActions.AuthenticateSuccessAction(user);
})
.catch(error => { console.log(error); return Observable.throw(error); })
);
The console logs the data variable and the AuthenticateSuccessAction
action is being triggered, so the router line is being executed but the navigation doesn't happen.
@Effect() public authenticate$ = this.actions$.pipe(
ofType(authenticationActions.AUTHENTICATE),
map(action => action.payload),
exhaustMap((auth: any) =>
this.authenticationService.authenticate(auth)
.map((data: TokenData) => {
return user: User = {
token: data.token,
username: 'dummy',
};
}).catch(error => { console.log(error); return Observable.throw(error);
}).pipe(
map(user =>new authenticationActions.AuthenticateSuccessAction(user))
)
);)
@Effect({ dispatch: false })
loginSuccess$ = this.actions$.pipe(
ofType(authenticationActions.AuthenticateSuccessAction),
tap(() => this.router.navigate(['/']))
);
Use exhaustMap and when you dispatching 'AuthenticateSuccessAction' action, do another effect for redirecting.
Personally, I like to separate all the services from effects, then you can use catchError() operator after success login for dispatching another action in case of failure login.
hope this works. PS: I did not verify this answer but logic is like this.