Here's my Angular auth guard. It checks for a logged in status, then gets an id from it if it exists and checks for a profile assigned to that id. I'm trying to resolve the guard waiting for this two observables to finish in order with the zip method, but checkProfileOnline is returning an error because the uid is undefined, therefore is not waiting for the first observable to finish.
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private authService: AuthService,
private userService: UserService,
private router: Router
) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
let obsArray: Observable<boolean>[] = [];
obsArray.push(this.checkAuthOnline(), this.checkProfileOnline());
// CHECK FOR AUTH AND PROFILE ONLINE
return Observable.zip(obsArray).map(res => {
if (res[0] && res[1]) {
return true;
}
return false;
});
}
checkProfileOnline(): Observable<boolean> {
return this.userService.userCheck(this.authService.uid).map(profile => {
if (profile) {
this.userService.user = profile;
return true;
}
this.router.navigate(['/']);
return false;
});
}
checkAuthOnline(): Observable<boolean> {
return this.authService.authStatus().map(loggedIn => {
if (loggedIn) {
this.authService.uid = loggedIn.uid;
return true;
}
return false;
});
}
}
Instead of zip
you can wait until the first observable is finished with concatMap
and then run the second on. Then the second result will be mapped to &&
operation on both of them.
return checkAuthOnline()
.concatMap(res1 => checkProfileOnline()
.map(res2 => res1 && res2)
)