Why does Angular injector detect the following provided even if its not in the injector heirarchy?

77 views Asked by At

From the official docs, following is an example of lightweight injection token pattern for enabling tree shaking:

abstract class LibHeaderToken {}

@Component({
  selector: 'lib-header',
  providers: [
    {provide: LibHeaderToken, useExisting: LibHeaderComponent}
  ]
  ...,
})
class LibHeaderComponent extends LibHeaderToken {}

@Component({
  selector: 'lib-card',
  ...,
})
class LibCardComponent {
  @ContentChild(LibHeaderToken) header: LibHeaderToken|null = null;
}

My question is that when Angular sees @ContentChild(LibHeaderToken), it will try to look for a provider with token name as LibHeaderToken, but it'll look for it on the current component or its parents (because its an hierarchical injector). It'll not look in LibHeaderComponent (which is where we have declared the required provider).

So why does this work and why LibHeaderComponent is also searched when looking for providers?

1

There are 1 answers

0
Fatih Ersoy On BEST ANSWER

If you look for the definition of @Contentchild decorator, it's written in the original docs:

The following selectors are supported.

  1. Any class with the @Component or @Directive decorator
  2. A template reference variable as a string (e.g. query <my-component #cmp> with @ContentChild('cmp'))
  3. Any provider defined in the child component tree of the current component (e.g. @ContentChild(SomeService) someService: SomeService)
  4. Any provider defined through a string token (e.g. @ContentChild('someToken') someTokenVal: any)
  5. A TemplateRef (e.g. query with @ContentChild(TemplateRef) template;)

In the bullet list, the 3rd bullet says "Any provider defined in the child component tree of the current component (e.g. @ContentChild(SomeService) someService: SomeService)". So in the example, LibCardHeader is in the child component tree of LibCardComponent, and the LibHeaderToken is a provider defined in the LibCardHeader -which is child component- which matches with the explanation "Any provider defined in the child component tree of the current component". The current component is LibCardComponent.

edit: docs reference