Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Inject() function doesn't provide router to CanActivateFn

I am trying to use one of the Angular v14 features which is CanActivateFn.

Unfortunately, when my guard is executed and the statement in return is false, I am not getting redirected. Error is being thrown:

Uncaught (in promise): TypeError: router.parseUrl is not a function TypeError: router.parseUrl is not a function

allowed-entities.guard.fn.ts

export function AllowedEntitiesGuard(allowedEntities: string[]): CanActivateFn {
  const router = Inject(Router);
  return (route: ActivatedRouteSnapshot) => {
    const entitiesTypeParameter = route.paramMap.get('entitiesType')

    return allowedEntities.indexOf(entitiesTypeParameter) !== -1 ? true : router.parseUrl('/');
  };
}

main.ts

bootstrapApplication(AppComponent, {
  providers: [
    provideHttpClient(withInterceptorsFromDi()),
    {
      provide: HTTP_INTERCEPTORS,
      useClass: JwtInterceptor,
      multi: true,
    },
    { provide: APP_CONFIG, useValue: environment },
    provideRouter(APP_ROUTES),
  ],
});

When I am trying to console.log router, it shows me its function ParamDecorator instance. What I am doing wrong?

like image 550
mhld Avatar asked Oct 30 '25 12:10

mhld


1 Answers

The problem was related to wrong import.

I should use inject instead of Inject.

allowed-entities.guard.fn.ts

// Good!
import { inject } from '@angular/core';

// Absolutely wrong!    
import { Inject } from '@angular/core';

Another thing. I cannot use inject() like above in the original post, because of NG0203. I had to move Router injection into CanActivateFn body, so it belongs to context.

I ended up with guard looking like that:

allowed-entities.guard.fn.ts

export function AllowedEntitiesGuard(allowedEntities: string[]): CanActivateFn {
  return (route: ActivatedRouteSnapshot): boolean | UrlTree => {
    const router: Router = inject(Router);
    const entitiesType: string | null = route.paramMap.get(
      'entitiesType'
    );

    return allowedEntities.indexOf(entitiesType) !== -1 ? true : router.parseUrl('/');
  };
}

With this approach, I can pass the entities directly into the guard. No need to specify additional data parameter and then retrieve it from ActivatedRouteSnapshot.

app.routes.ts

canActivate: [AllowedEntitiesGuard(['EntityTypeOne', 'EntityTypeTwo'])
like image 150
mhld Avatar answered Nov 02 '25 03:11

mhld



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!