Using hostDirectives inside Directives easily leads to error NG0309
See original GitHub issueWhich @angular/* package(s) are relevant/related to the feature request?
core
Description
By using the shiny new hostDirectives API, I’ve found myself easily running into error NG0309.
NG0309: Directive MyDirective matches multiple times on the same element. Directives can only match an element once.
In my case I am using a DestroyDirective (for handling rxjs subscriptions).
Sample repository: https://github.com/TomTomB/multiple-same-host-directive-issue
In it is a component with a template, that uses 2 directives on the same element (app-a and app-b)
<div app-a app-b></div>
Both directives have the following logic:
@Directive({
selector: '[app-a]',
standalone: true,
hostDirectives: [DestroyDirective],
})
export class ADirective {
private readonly _destroy$ = inject(DestroyDirective).destroy$;
}
This results in the error mentioned above. The error is, of cause, not only specific to this exact use case. I fact, it’s a pretty big road block when thinking the new “composition way” of reusing code. Also, the error is really not that helpful for explaining, why this code is not working. This could especially be true when using 3rd party packages that use hostDirectives on their own.
Proposed solution
Using hostDirecitves inside a directive should never result in a NG0309 error.
Alternatives considered
Removing hostDirecitves from the Directive decorator - but that would be a big bummer imho.
Issue Analytics
- State:
- Created 10 months ago
- Reactions:7
- Comments:9 (3 by maintainers)
Top Related StackOverflow Question
I consider tricks like
DestroyDirectiveto be an anti-pattern in the first place. The purpose ofhostDirectivesis not to provide some kind of injection mechanism for lifecycle hooks, but for one directive to compose behaviors from another. In that sense, it’s perfectly valid to disallow multiple directives attempting to apply the same host directive.Hey @alxhub, I think just focusing on my example
DestroyDirectiveis a litte short-sighted, since this issue applies to all directives. Let’s use the angular/components library as an other example. They are currently using class mixins for things like adisabledboolean. So withhostDirectivesI would assume that we should now be able to create aCanDisableDirective. Applying this to my issue repo would yield the same result - NG0309. So composition is a thing now, but not really.