How to export a functional guard

128 views Asked by At

I have a functional guard that I would like to export from one of my libraries.

Initially the guard looked like this:

export const canActivateAuthenticationFn: CanActivateFn = () => { 
  const authService: AuthService = inject(AuthService);
  const logger: LoggerService = inject(LoggerService);

  if (authService.isLoggedIn()) {
    logger.log("Login: successful");
    return true;
  } else {
    logger.log("Login: unsuccessful");
    return false;
  }
}

And it was in a file named authentication.guard.ts .

But then I read that you can't export constants from libraries, so I tried to export it as a function:

export function canActivateAuthenticationFn(): CanActivateFn {
const authService: AuthService = inject(AuthService);
const logger: LoggerService = inject(LoggerService);

   if (authService.isLoggedIn()) {
      logger.log('Login: successful');
      return true;
   } else{
    logger.log('Login: unsuccessful');
    return false;
   }
}

I also exported the function in my public-api.ts:

export * from '.lib/...../authentication-guard'

For me it looked like it would work I was able to use the function in my project.

But then at runtime I got the following error:

ERROR: Error: Uncaught (in promise): Error: NG0203: inject() inject must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with 'runInInjectionContext'.

So what would I have to do to export my guard function from my library and use it in my project? And is my File name, where the guard function is declared alright?

Thanks for the help.

1

There are 1 answers

0
Naren Murali On

As per the error message runInInjectionContext will solve your problem, could you try the below steps?

Create a new function in your main code (not in library)

// import your canActivateAuthenticationFn from the library here! 

export const canActivateAuthenticationFn: CanActivateFn = () => { 
    const environmentInjector = inject(EnvironmentInjector);
    return runInInjectionContext(this.environmentInjector, 
               canActivateAuthenticationFn.bind(this));
}

Then finally add this function to your routing and check if it works?