angularroutesangular-router-guards

Angular 15: Empty ActivatedRoute params in Functional Route Guards


I use new functional guards like:

export function AuthGuard() {
  const route = inject(ActivatedRoute);
  const authService = inject(AuthService);

  return authService.state$.subscribe((user) => {
    return user.uuid === route.snapshot.params.uuid;
  });
}

In the moment, current data of route.snapshot.params is empty. Subscription on Router events or ParamsMap does not give result.

Otherwise, when i use class-based guards with CanActivate, route data from ActivatedRouteSnapshot works perfectly, but authService get only first emit with undefined.

I figured out a workaround with placing combineLatest([route, authService]) with redirects in the Component, that need's this Guard.

I'm stuck. No way.

Solution: the main problem was in using BehaviorSubject in my authService, replacing to ReplaySubject solved first problem. Resolver usage solved the second part.


Solution

  • Actually you don't need to inject ActivatedRoute. If you want to read params from snapshot, your guard could look like this:

    export function authGuard(snapshot: ActivatedRouteSnapshot) {
      const authService = inject(AuthService);
    
      return authService.state$.subscribe((user) => {
        return user.uuid === snapshot.params.uuid;
      });
    }
    

    Please note here, that I've added ActivatedRouteSnapshot as function param, instead of ActivatedRoute.
    Now when you assign this function to canActivate in route definition just make sure you pass snapshot to this function:

    {
      path: ':uuid',
      canActivate: [(snapshot: ActivatedRouteSnapshot) => authGuard(snapshot)],
    },