Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

Angular

Angular HostBinding and HostListener

What are HostBinding and HostListener decotarors in angular and how to use those in your directive to listen events and identify properties

What is HostBinding

Based on the Angular document HostBinding is “Decorator that marks a DOM property as a host-binding property and supplies configuration metadata”. It actually means HostBinding provides access to the host component properties and attribute inside the component or directive

Let’s say we want to set a border using the directives to the element. We can use HostBinding to achieve that.

import { Directive, HostBinding } from '@angular/core';

@Directive({
  selector: '[border]'
})
export class BorderDirective {
  
  constructor() { }

  @HostBinding('style.border')  border: string ='1px solid red';

}
<p border> this is a bordered text</p>

What is HostListener

This province is a handler which executes based on different events. Let’s add a simple HostListener to show an alert when the user click on the component which has the directive border.

import { Directive, HostBinding, HostListener } from '@angular/core';

@Directive({
  selector: '[border]'
})
export class BorderDirective {

  constructor() { }

  @HostBinding('style.border')  border: string ='1px solid red';

  @HostListener('click') onClickElement():void{
    alert('Clicked')
  }
}

How to add styling when click the element click

Most of the articles and solutions suggest changing just border value and It refect to the UI. But based on my testing it seems to no longer works.

import { Directive, HostBinding, HostListener } from '@angular/core';

@Directive({
  selector: '[border]'
})
export class BorderDirective {

  constructor() { }

  @HostBinding('style.border')  border: string | undefined;

  @HostListener('click') onClickElement():void{
    this.border = "1px solid green"; //notworking
  }
}

Therefore we need to add following two classes to make it work

constructor(private el:ElementRef,private render:Renderer2) { }

ElementRef is kind of wrapper to the element which give access to the native element. Renderer2 will help to add a style to element and rerender the component .

import { Directive, ElementRef, HostBinding, HostListener, Renderer2 } from '@angular/core';

@Directive({
  selector: '[border]'
})
export class BorderDirective {

  constructor(private el:ElementRef,private render:Renderer2) { }

  @HostBinding('style.border')  border: string = "1px solid red";

  @HostListener('click') onClickElement():void{
    this.render.setStyle(this.el.nativeElement,'border','1px solid green')
  }
}

Create a listener to input blur

Let’s say we want to get the input value when the user unfocus the input. For that, we can listen to the blur event. In the second argument, we can specify what are the values which need to pass. In there we can access the input value using the event.target.value and pass to the function

import { Directive, HostListener } from '@angular/core';

@Directive({
  selector: '[blur]'
})
export class BlurDirective {

  constructor() { }

  @HostListener('blur', ['$event.target.value'])
  inputBlur(value:string) {
    console.log('Input ',value);
  }
  
}

Enter key press

@HostListener('document:keydown.enter')

Escape key press

@HostListener('document:keydown.escape')

Mouse over the element

@HostListener('mouseover')

Mouse out of the element

@HostListener('mouseout')

Other than these events there are a lot of events available and you can use them based on your need

What are some use cases for HostListener?

It really hard to define specific use cases in which we can use HostListener. You can use it anywhere based on your need. These are some common use cases which I have in my bind

  • Implement highlighter
  • Implement log trigger in certain event(Capture telemetry data)
  • toggle classes to add different styles based on different event