79290604

Date: 2024-12-18 09:35:15
Score: 1.5
Natty:
Report link

I know this is an old topic, but I think you are looking for the useExisting option of the provider, which must be placed on the directive itself.

So if you have an injection token FLASHY_TOKEN and a directive FlashyDirective that implements the appropriate interface, then the FlashyDirective must provide "itself" on that given injection token. Something like this:

export const FLASHY_TOKEN = new InjectionToken<IFlashy>('IFlashy');

@Directive({
  selector: '[flashyDirective]',
  providers: [
    { provide: FLASHY_TOKEN, useExisting: forwardRef(() => FlashyDirective) },
  ],
})
export class FlashyDirective implements IFlashy {}

The forwardRef is used because at that line, the class itself is not yet fully defined. From the linked documentation:

The order of class declaration matters in TypeScript. You can't refer directly to a class until it's been defined. [...] You face a similar problem when a class makes a reference to itself

It does not seem to be 100% necessary with the current (v19) version of Angular, but it doesn't make anything worse, so I tend to use it in these cases.

With useExisting you can basically forward one token to another. There is a good example in the docs that uses a similar approach:

Angular recognizes the directive's role in the validation process because the directive registers itself with the NG_VALIDATORS provider [...]

Notice that the custom validation directive is instantiated with useExisting rather than useClass. The registered validator must be this instance of the ForbiddenValidatorDirective. [...]

If you were to replace useExisting with useClass, then you'd be registering a new class instance, one that doesn't have a forbiddenName.

Also, here is an oversimplified stackblitz example

Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • Me too answer (2.5): face a similar problem
  • Low reputation (0.5):
Posted by: csisy