5

I have a component protected with canActivate guard. The Authguard in the checkLogin function subscribes from an observable but I do not know how to return a boolean value from it to canActivate.

guard.service.ts

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    let url: string = state.url;

    return this.checkLogin(url);
  }

    public checkService:boolean;
  checkLogin(url: string):boolean {

         return this.loadAppSettings().subscribe(res=>{
              console.log(this.checkservice);
              if (this.checkservice == true) 
              {
                   return true; 
            }
            else{
                this.router.navigate(['/error-user']);
                return false;
            }
            });
      }//checkLogin throws error as type subscription is not assignable to type boolean

So what I want is if the this.checkService is true it should just return true and the user should be able to land on the guarded route but if it is false he should be navigated to error-user.

Angular2 - return boolean with subscribe to canActivate this question is similar to mine but couldn't resolve my issue with it.

Can somebody help here.

Community
  • 1
  • 1
Aakash Thakur
  • 3,837
  • 10
  • 33
  • 64
  • @Igor is the duplicate still relevant if the asynchronous call returns an observable instead of a promise? – David L Apr 19 '17 at 20:06
  • @DavidL - I would think so. An observable is nothing more than a promise with more calls on it. Also observable can be converted to a promise by using `.toPromise()`. Also the OP has shown that they can subscribe to the observable, now its just a matter of them understanding how to use the whole concept of a callback. – Igor Apr 19 '17 at 20:08
  • @Igor my point is that it may be related, but it isn't an exact duplicate. There are subtleties that make it a poor duplicate choice. The OP's linked question is actually a far better duplicate. – David L Apr 19 '17 at 20:10
  • Yes @DavidL exactly and if marked duplicate it will be left answered. – Aakash Thakur Apr 19 '17 at 20:12
  • @AakashThakur I'm not giving you a free hall pass either :). You are responsible for doing your own research to understand how callbacks and asynchronous code and you've already linked an answer that essentially solves your question. – David L Apr 19 '17 at 20:13

2 Answers2

11

canActivate can return an observable too, see the definition CanActivate-interface. Just change your return types accordingly.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    let url: string = state.url;

    return this.checkLogin(url);
}

public checkService:boolean;
checkLogin(url: string):Observable<boolean> {
     return this.loadAppSettings().map(res=>{
          console.log(this.checkservice);
          if (this.checkservice == true) 
          {
               return true; 
        }
        else{
            this.router.navigate(['/error-user']);
            return false;
        }
    });
  }
Igor
  • 60,821
  • 10
  • 100
  • 175
1

We can return Promise too like...

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Promise<boolean> {
    return new Promise<boolean>(resolve => {
       this.service
       .function()
       .toPromise()
       .then((res) => {
         if(condition) {
            resolve(true);
         } else {
            this.router.navigate(["login"]);
            resolve(false); 
         } 
      })
      .catch(() => {
        this.router.navigate(["login"]);
        resolve(false);
       });
    });
  }
Vikram Sapate
  • 1,087
  • 1
  • 11
  • 16