How to wait for the completion of an Effect in NgRx. I am stuck in this situation. I have an effect that loads a token from the storage and the dispatch an action to update the Store depending that the token was found or not.
autoLogin$ = createEffect(() => this.actions$.pipe(
ofType(AuthActions.startAutoLogin),
switchMap(action => {
return from(AuthUtils.getTokenFromStorage(USER_TOKEN_STORAGE_KEY));
}),
switchMap(token => {
if (AuthUtils.isProvidedTokenNotExpired(token)) {
return from(AuthUtils.getTokenData(token));
}
return EMPTY;
}),
map(tokenData => {
if (tokenData) {
return AuthActions.autoLogin({payload: tokenData});
}
})
));
The action AuthActions.autoLogin({payload: tokenData})
is dispatched and used to update one field in the store:
export interface AuthState {
isLoggedIn: boolean,
}
Finally I use that field in a Router Guard to check if the user is logged in or not:
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanLoad, CanActivate {
constructor(private router: Router,
private store: Store<fromAuth.AuthState>) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.store.select(AuthSelectors.selectIsLoggedIn).pipe(
tap(isLoggedId => {
if (!isLoggedId) {
this.router.navigateByUrl('/login').then();
}
}),
);
}
}
The problem is:
The Router Guard is executed before the Effect, the Store is updated too late and user is redirected to the login page. When I look at the state of the store after the redirection, isLoggedIn
is true
.
Is it possible in the Router Guard to wait the end of the Effect execution redirecting or not?