0

Below are my code, what im tring to do is im trying to get return value directly into canActivate return, but the problem is it will run the checking first before run "this._authService.isAdmin(token)" method. i know it like that because of async. But how to prevent that? i already run of idea. thanks in advance.

i already try putting that method on construtor but the result still same.

import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { AuthenticationService } from "../_services/authentication.service";

@Injectable()
export class AdminGuard implements CanActivate  {

  isAdmin: boolean = false;

  constructor(
    private _authService: AuthenticationService,
    private router: Router) {
  }

  canActivate(): Observable<boolean> | Promise<boolean> | boolean {

  var token = this._authService.getJwtToken();
  this._authService.isAdmin(token).subscribe(
     res => {
            //res will return true or false value
            this.isAdmin = res;
     }
  );

  if(this.isAdmin){
    return true;
  }
  this.router.navigate(['/']);
  return false;

  }
}
FlyingTurtle
  • 145
  • 4
  • 19

1 Answers1

0

You can use pipeable operators for this:

canActivate(): Observable<boolean> {
  let token = this._authService.getJwtToken();
  return this._authService.isAdmin(token).pipe(
    tap(isAdmin => {
      if (isAdmin) {
        this.router.navigate(['/']);
      }
    })
  );
}

// Usage:
canActivate.subscribe(value => {
  // do something...
});

Note that the tap operator simply performs a "side effect task". The returned observable from the tap operator is the same as the one before it. Now the if isAdmin check within the tap operator is only evaluated once the isAdmin observable emits an event.

Sam Herrmann
  • 6,293
  • 4
  • 31
  • 50