Angular Guard with Parameters

The ‘default’ Guard when creating is something like this:

export const AdminGuard: CanActivateFn = async (_, state: RouterStateSnapshot) => {
  const profileFacade = inject(ProfileFacade);

  const userRoles = await firstValueFrom(profileFacade.roles$);

  return userRoles.includes('admin')
};

Instead of making a guard for every type of role, we can make the current guard more flexible as follows:

type ExistingRoles = 'reader' | 'owner' | 'admin';

export const RolesGuard: (roles: ExistingRoles []) => CanActivateFn = (roles) => async (_, state: RouterStateSnapshot) => {
  const profileFacade = inject(ProfileFacade);

  const userRoles = await firstValueFrom(profileFacade.roles$);

  return roles.some((role) => userRoles.includes(role));
};

And use it in the routing as such:

  {
    path: 'admin',
    canActivate: RolesGuard(['admin']),
  },