Home > Blockchain >  canActivate not waiting for observable (Angular 13)
canActivate not waiting for observable (Angular 13)

Time:04-06

I've seen a few answers on SO regarding this same topic, but I believe in Angular 13.x the behavior is different. In the below code, canActivate needs to return an observable boolean. So all code paths MUST return an observable boolean, if I remove this line:

return of(valid); // always hits first

I get a compile error:

error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.

This makes sense. I need to return an observable boolean. However I am still unsure how to have canActivate wait for this.authService.authCheck() to return the response?

Here is what I tried:

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable, of, map, catchError, observable } from 'rxjs';
import { AuthService } from '../data/auth.service';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(private authService: AuthService, private router: Router) { }

  canActivate(
    route: ActivatedRouteSnapshot): Observable<boolean> {

    var valid = false;
    this.authService.authCheck().subscribe(response => {
      if (!response) {
        this.router.navigateByUrl('login');
        valid = false;
        return valid;
      } else {
        valid = true;
        return valid;
      }
    });
    return of(valid); // always hits first

  } 
}

I have tried map also

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {

this.authService.authCheck().pipe(map(r => {
  if (!r) {
    console.log("failure");
    this.router.navigateByUrl('login');
    return false;
  } else {       
    return true;
  }
})); // error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.

}

CodePudding user response:

You should return Observable so your first approach with the subscribe is not correct. You were pretty close with the second one - you're missing return.

Following code should work:

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
   return this.authService.authCheck().pipe(map(r => {
     if (!r) {
       console.log("failure");
       this.router.navigateByUrl('login');
       return false;
     } else {       
       return true;
     }
}));
  • Related