angulardependency-injectionangular17angular-guards

inject in Authentication guard is giving me type any in angular 17


I create a functional guard in angular 17

import { Inject } from '@angular/core';

export const checkoutGuard: CanActivateFn = (route, state) => {
    const customerService = Inject(CustomerService);
    const router = Inject(Router);
    if(customerService.isAuthenticated()) {
         return true;
    } else {
         return router.navigateByUrl('/login');
    }
};

I get the error customerService.isAuthenticated is not a function. I declared the service in app.config.ts providers: [provideRouter(routes), provideHttpClient(), CustomerService,] this what iI declared in routes {path:'checkout', component:CheckoutComponent, canActivate:[checkoutGuard]} this is the service class

@Injectable({   providedIn: 'root' }) 
export class CustomerService { 
     isAuthenticated():boolean {    return true;   } 
}

Solution

  • The root cause of the issue is to use inject instead of Inject, please change it

    import:

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

    inject -> used outside constructor to load dependencies from DI

    Inject -> used inside constructor to load dependencies from DI (sometimes needed)


    We can remove CustomerService from the app.config.ts providers array, since that is reserved for environment providers only, then in the customers service we can set providedIn: root, which means the service is accessible throughout the application, so even inside guards!

    @Injectable({
        providedIn: 'root',
    })
    export class CustomerService {
        ...
    

    Then you need to check how you have defined, isAuthenticated it should be a function/method, if its a property please change the if condition to

    export const checkoutGuard: CanActivateFn = (route, state) => { 
        const customerService = inject(CustomerService); 
        const router = inject(Router); 
        if(customerService.isAuthenticated) { 
            return true; 
        } else { 
            return router.navigateByUrl('/login'); 
        } 
    };