Host Decorator In Angular

Host Decorator In Angular

The @Host decorator is one of Angular's Resolution Modifiers. @Self, SkipSelf, and Optional are the others. The DI Framework's dependency resolution is controlled by these Decorators. @Self, @SkipSelf, and @Optional Decorators have already been discussed. In this article, We will learn everything there is to know about @Host.

@Host

It's a little difficult to understand the definition. So let's attempt to make things a little clearer.

  • The @Host property only looks for dependencies within the component's template.
  • It starts with the current Injector and moves up the Injector hierarchy until it finds the current component's host element.
  • It does not look for the dependent in the host element's Providers.
  • However, it does look in the host element's ViewProviders.
  • When the @Host flag is set, the module injector is never searched.

It resembles @Self in appearance. However, @Self only checks in the current component's Injector.

The @Host, on the other hand, looks for the dependent in the current template.

@Host Example

Let's have a peek at Angular Example. It's the same example as the @Self, @SkipSelf, and @Optional Decorators artcile.

It is made up of three parts. AppComponent, ChildComponent, and GrandChildComponent are three types of components. There is just one testDirective directive. When RandomService is instantiated, it generates a random number.

The random number from the RandomService is displayed in all components and directives.

Make all components and directives' Providers null so that the AppModule always provides RandomService. When you run the app, all of the components and directives should display the same number. In addition, you will only see the RandomService Constructed message in the terminal window once, indicating that only one instance of the service has been built.

Parent & Child Components with @Host Decorator

GrandChildComponent has been introduced to the ChildComponent template.

@Component({
  selector: "my-child",
  providers: [],
  viewProviders: [],
  template: `
    <div class="box">
      <p>ChildComponent => {{ randomNo }}</p>
 
      <my-grandchild></my-grandchild>
    </div>
  `
})
export class ChildComponent {

Add the @Host decorator to the randomService in the GrandChildComponent now.
export class GrandChildComponent {
  randomNo;
  constructor(@Host() private randomService: RandomService) {
    this.randomNo = randomService?.RandomNo;
  }
}

You will, Immediately receive the message.

The GrandChildComponent is included in the ChildComponent template. The ChildComponent is where this Template resides. As a result, the host component is ChildComponent.
<div class="box">
  <p>ChildComponent => {{ randomNo }}</p>

  <my-grandchild></my-grandchild>
</div>

@Host checks for Dependency in the template first. It all starts with the GrandChildComponent's Providers.

Then it'll go to the Host Component, which is ChildComponent. It will only look in the ViewProviders array, not the Providers array, in this case.

As a result, there are two options for resolving this issue.

Add the RandomService to the GrandChildComponent's Providers. Because that's where DI searches for dependencies first.

The second option is to add RandomService to the ChildComponent's viewProviders array.

Directives & @Host Decorator

The Components are nothing more than Directives with a View attached to them. As a result, directives function in the same way.

Add the @host decorator to randomService in the testDirective. The error appears in the console window right away. In NodeInjector, there is no RandomService provider.
export class testDirective implements OnInit {
  constructor(
    private el: ElementRef,
    @Host() private randomService: RandomService
  ) {}
  
This template from GrandChildComponent includes the testDirective. GrandChildComponent is the template's host.
template: `
  <div class="box">
    GrandChildComponent => {{ randomNo }}

    <div class="dirbox" testdirective="">fdf</div>

  </div>
`,

In this order, @Host will seek for the Dependency.
  1. Providers array of testDirective
  2. ViewProviders of the GrandChildComponent

As a result, putting the RandomService in either of those places will fix the problem.

Multiple Directives

There are three directives in this section. RandomService is required by all of them.

Add @Host to RandomService in cDirective now.

Take a look at the template where we used cDirective to see how @Host resolves the Dependency.

The template for the ChildComponent component (Hence our Host Component). This template includes the aDir, bDir, and cDir folders. As previously stated, when resolving the dependency, @Host only looks at this template.
<div class="box">
  <p>ChildComponent => {{ randomNo }}</p>

  <div adir="">
    <div bdir="">
      <div cdir=""></div>
    </div>
  </div>
</div>

In this order, @Host will seek for the Dependency.
  1. Providers of cDirective
  2. Providers of bDirective
  3. Providers of aDirective
  4. ViewProviders of ChildComponent

Put RandomService in either of those locations, and the fault will be resolved.

What if we use @Host instead of cDirective in bDirective? The following is the order in which the checks will be performed. Because it is the child of bDirective, cDirective is not tested.
  1. Providers of bDirective
  2. Providers of aDirective
  3. ViewProviders of ChildComponen

Content Projection & @Host Decorator

The App is made up of three parts (AppComponent, ChildComponent, and GrandChildComponent), as well as a service (RandomService). To project the GrandChildComponent into the ChildComponent, we're using Content Projection.

Add the @Host decorator to randomService in the GrandChildComponent.

Let's have a look at the template where the GrandChildComponent is located, just as we did in the prior examples. It may be found in the AppComponent's template.
<div class="box">
  <p>AppComponent => {{ randomNo }}</p>
  <my-child>
    <my-grandchild></my-grandchild>
  </my-child>
</div>

As a result, the above is our template, and AppComponent is the host.

In this order, @Host will seek for the Dependency.
  • Providers of GrandChildComponent
  • Providers of ChildComponent
  • ViewProviders of AppComponent


Conclusion

In this article, We covered everything there is to know about @Host.

I hope this article helps you and you will like it.👍

If you have any doubt or confusion then free to ask in comment section.

Post a Comment

Previous Post Next Post