user9487981
user9487981

Reputation:

can activate guard and using observables with in them angular 5

I am using a route guard that implements canActivate

I have placed a bunch of console logs in the code to understand where it is failing.

what happens is if I navigate to the protected route. The navigation fails because the guard fails to return a value. The http map I have is not finishing.

I currently have a JWT token saved in my session storage but not in my local

these are the console logs I get when I run the guard

running the local check

running the session check

got session token authorizing it

then the http map comes back and then code breaks.

The full code is below. Help would be appreciated!

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import {
  CanActivate,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
  Router
} from '@angular/router';
import {Injectable} from '@angular/core';
import {UserAuthorizationService} from "../userauthorizationservice/userauthorizationservice";


@Injectable()
export class ClientSuitsAdminSuperUserGuard implements CanActivate{
  constructor(private userservice: UserAuthorizationService, private router: Router){}
  user ={
    id: null,
    isclient: false,
    issuitsviewer: false,
    issuitsadministrator: false,
    issuitssuperuser: false,
    isvenueuser: false

  };

  canActivate(route: ActivatedRouteSnapshot,
              state: RouterStateSnapshot): Observable<boolean> | boolean {

    let token = this.userservice.checklocalfortoken();
    console.log('running the local check');
    if(token == null){
      console.log('running the session check');
      token = this.userservice.checksessionfortoken();
      if(token == null){
        console.log('no session token nav to sign in return false');
        this.router.navigate(['/signin']);
        return false;
      }
      console.log('got session token authorizing it');
      this.userservice.returnauthorizetoken(token)
        .map(
          (req: any)=>{
            this.user = req;
            console.log('this is the user object from the session auth');
            console.log(this.user);
            if(this.user.isclient || this.user.issuitsadministrator || this.user.issuitssuperuser){
              console.log('the user has permissions from the session');
              return true;
            }else{
              console.log('the user does  not have permissions from the session');
              this.router.navigate(['/401']);
              return false;
            }
          },
          error => {
            console.log('error with the session authorization');
            this.router.navigate(['/signin']);
            return false;
          }
        );

    }else{
      console.log('doing the local check');
      this.userservice.returnauthorizetoken(token)
        .map(
          (req: any)=>{
            this.user = req;
            console.log('got the user object from the local');
            console.log(this.user);
            if(this.user.isclient || this.user.issuitsadministrator || this.user.issuitssuperuser){
              console.log('user has permissions from the local');
              return true;
            }else{
              console.log('user does not have permissions from the local');
              this.router.navigate(['/401']);
              return false;
            }
          },
          error => {
            console.log('error from the local authorization');
            this.router.navigate(['/signin']);
            return false;
          }
        );
    }
  }

}

Upvotes: 4

Views: 6619

Answers (2)

Prachi
Prachi

Reputation: 3574

Use it like this:

        canActivate(route: ActivatedRouteSnapshot,
                  state: RouterStateSnapshot): Observable<boolean> | boolean {
        let token = this.userservice.checklocalfortoken();
        console.log('running the local check');
        if(token == null){
          console.log('running the session check');
          token = this.userservice.checksessionfortoken();
          if(token == null){
            console.log('no session token nav to sign in return false');
            this.router.navigate(['/signin']);
            return false;
          }
          console.log('got session token authorizing it');
          //subscribe method_first and return boolean  variable from here
        }else{
       //subscribe method_second and return boolean  variable from here
        }
      }



       method_first(token): observable<any>{
       this.userservice.returnauthorizetoken(token)
            .map(
              (req: any)=>{
                this.user = req;
                console.log('this is the user object from the session auth');
                console.log(this.user);
                if(this.user.isclient || this.user.issuitsadministrator || this.user.issuitssuperuser){
                  console.log('the user has permissions from the session');
                  return true;
                }else{
                  console.log('the user does  not have permissions from the session');
                  this.router.navigate(['/401']);
                  return false;
                }
              },
              error => {
                console.log('error with the session authorization');
                this.router.navigate(['/signin']);
                return false;
              }
            );
      }

      method_second(token): observable<any>{
      console.log('doing the local check');
          this.userservice.returnauthorizetoken(token)
            .map(
              (req: any)=>{
                this.user = req;
                console.log('got the user object from the local');
                console.log(this.user);
                if(this.user.isclient || this.user.issuitsadministrator || 
    this.user.issuitssuperuser){
                  console.log('user has permissions from the local');
                  return true;
                }else{
                  console.log('user does not have permissions from the local');
                  this.router.navigate(['/401']);
                  return false;
                }
              },
              error => {
                console.log('error from the local authorization');
                this.router.navigate(['/signin']);
                return false;
              }
            );
    }

Upvotes: 0

Teddy Sterne
Teddy Sterne

Reputation: 14221

You need to return an observable from canActivate that emits a boolean value. Under the hood Angular subscribes to the observable that is returned and then handles the routing correctly based on the emitted value.

Your code should work if you return the call to your userservice.

Updated

@Injectable()
export class ClientSuitsAdminSuperUserGuard implements CanActivate{
  constructor(private userservice: UserAuthorizationService, private router: Router){}
  user ={
    id: null,
    isclient: false,
    issuitsviewer: false,
    issuitsadministrator: false,
    issuitssuperuser: false,
    isvenueuser: false

  };

  canActivate(route: ActivatedRouteSnapshot,
              state: RouterStateSnapshot): Observable<boolean> | boolean {

    let token = this.userservice.checklocalfortoken();
    if (token == null) {
      token = this.userservice.checksessionfortoken();
      if(token == null){
        this.router.navigate(['/signin']);
        return false;
      }
      return this.userservice.returnauthorizetoken(token)
        .map(
          (req: any)=>{
            this.user = req;
            console.log('this is the user object from the session auth');
            console.log(this.user);
            if(this.user.isclient || this.user.issuitsadministrator || this.user.issuitssuperuser){
              console.log('the user has permissions from the session');
              return true;
            }else{
              console.log('the user does  not have permissions from the session');
              this.router.navigate(['/401']);
              return false;
            }
          },
          error => {
            console.log('error with the session authorization');
            this.router.navigate(['/signin']);
            return false;
          }
        );

    } else {
      console.log('doing the local check');
      return this.userservice.returnauthorizetoken(token)
        .map(
          (req: any)=>{
            this.user = req;
            console.log('got the user object from the local');
            console.log(this.user);
            if(this.user.isclient || this.user.issuitsadministrator || this.user.issuitssuperuser){
              console.log('user has permissions from the local');
              return true;
            }else{
              console.log('user does not have permissions from the local');
              this.router.navigate(['/401']);
              return false;
            }
          },
          error => {
            console.log('error from the local authorization');
            this.router.navigate(['/signin']);
            return false;
          }
        );
    }
  }

}

Upvotes: 7

Related Questions