3
votes

I have an route guard on one of my private routes and when guard returns false it is not called again anymore. The following example is simplified how to reproduce such situation.

When user navigates using link:

<a [routerLink]="['my-private-route']">Link</a>

the guard gets called and I see called message in the console and navigation is canceled (I return false in guard):

@Injectable()
export class CanActivateViaAuthGuard implements CanActivate {
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean {
    console.log('called')
    return false;
  }
}

However when user clicks on the link again nothing happens.

Why I need such behaviour? The reason I need guard to be called repeatedly is because I have to display modal Do you want to login? YES/NO. When user clicks no I want to stay on the page. But when he laters decides to navigate again I want to let him login again.

Is there any way to stop angular2 caching guard results?

2
Please provide a Plunker to reproduce. I'd expect this to work as well. - Günter Zöchbauer
@GünterZöchbauer interesting. I made that plunker and indeed it works there. plnkr.co/edit/17CBn14zPuyrAhVnS4pA I will investigate how my code differs. Thank you :-) - Martin Nuc
@GünterZöchbauer the difference was Angular 2.2.0 vs 2.1.2. Looks like this guard caching appears in 2.2.0. - Martin Nuc
I'd report it as bug. It doesn't make sense to me. The guard needs to be re-evaluated every time. - Günter Zöchbauer

2 Answers

4
votes

After some investigation and help of @GünterZöchbauer it's a strange behaviour of angular router 3.2.0. There is already similar issue: https://github.com/angular/angular/issues/12851

Here is plunker with 3.1.2 where guard is evaluated every time:

https://plnkr.co/edit/jUhVJY?p=preview

Here is plunker with 3.2.0 where guard is evaluated only once:

https://plnkr.co/edit/2A0Wfu?p=preview

2
votes

I ran into the same issue. It looks like the behavior can be overridden in 4.x:

https://angular.io/api/router/Routes

Check for runGuardsAndResolvers route parameter.

I also wrongly assumed the value "always" would be used in router 3.4.x