0

I have a service with this function that returns true or false on rather or not a token is valid

loggedIn() {
return this.http.get('http://localhost:3000/users/validateToken')
  .map(res => res.json()).map(data => data.success);
}

I have a auth guard with can activate on protected routes that uses this.

  canActivate(){
    this.authService.loggedIn().subscribe(res => {
      if(res) {
        return true;
      }
      else {
        this.router.navigate(['/login'])
        return false;
      }
    })
  }

But i get this error.

incorrectly implements interface 'CanActivate'. Types of property 'canActivate' are incompatible. Type '() => void' is not assignable to type '(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => boolean | Promise | Obser...'. Type 'void' is not assignable to type 'boolean | Promise | Observable'.

How can i implement what I'm trying to do here ?

Thangadurai
  • 2,573
  • 26
  • 32
Anders Pedersen
  • 2,255
  • 4
  • 25
  • 49

1 Answers1

3

The canActivate function must return a boolean, a promise of a boolean, or an observable of a boolean.

In your case, you return nothing. Probably because you ommited the return in your function.

But it wouldn't work if you add it, because then, you would return a subscription, which isn't accepted by the signature.

What you could do is this :

canActivate() {
  return this.authService.loggedIn().map(res => {
    if(!res) {
      this.router.navigate(['/login']);
    }
    return res;
  });
}

With this code, you comply with the signature, and keep your routing logic.

  • What's the need to use `.map` function again when it was already gets used in the service layer, so dont you think in canActivate you need to use `subscribe` ? – Pardeep Jain Jun 06 '18 at 10:13
  • Also just curious to know, if we replace `.subscribe` with `.map` then your answer is similer to mine isn't it ? – Pardeep Jain Jun 06 '18 at 10:14
  • 1
    Using `map` again allows one to implement custom logic inside the guard. The first `map` is used in the auth service, meaning it can't interact with the guard. And `map` returns an Observable, meanwhile `subscribe` returns a Subscription. So no, the answers aren't similar, because mine is following the signature, and yours isn't. –  Jun 06 '18 at 10:15