Today we are learning about the host listener decorator in Angular and how we can use it in our workflows.
Developers of all levels, from beginners to experts can read this post—it does not matter if you are familiar with beginner concepts in Angular. Here are a few things you should have to be able to follow through this article’s demonstration:
Other nice-to-have’s include:
There are a couple of ways to listen to DOM events in your Angular project. The most popular way is by accessing the DOM directly using event listeners. But what if I told you there is another way that requires fewer lines of code, is memory efficient, and is great for readability and debugging?
According to the official docs, the Hostlistener is a decorator that declares a DOM event to listen for and provides a handler method to run when that event occurs. Angular invokes the supplied handler method when the host element emits the specified event and updates the bound element with the result.
To show how it is used, we will be building a simple accessibility page reader or subtitle for people who might find it difficult to read details on a webpage.
Let us start with creating a new Angular application using the CLI. Open your terminal to a file location of choice, and run this command:
ng new host
Replace the content in the app component HTML file with this code block:
<style>
p {
display: block;
margin: 2em 1em;
font-size: 30px;
background-color: #4CAF50;
}
</style>
<div>
<p>This is the first paragraph</p>
<p>This is the second paragraph</p>
<p>This is the third paragraph</p>
</div>
To create the subtitle directive, run this command:
ng generate directive subtitle
Our app should create a subtitle.directive.ts file like this:
import { Directive } from '@angular/core';
@Directive({
selector: '[appSubtitle]'
})
export class SubtitleDirective {
constructor() { }
}
Let us try out a very simple substitute illustration. Copy the code block below into the directive file:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[appSubtitle]'
})
export class SubtitleDirective {
@HostListener('mouseenter') onMouseEnter() {
alert("You just hovered over a paragraph");
}
}
Here we set a new host listener that basically alerts you once you hover over the element the listener points to. To point to an element in the app component, copy the selector “appSubtitle” and make it an element property in the HTML file like this:
<style>
p {
display: block;
margin: 2em 1em;
font-size: 30px;
background-color: #4CAF50;
}
</style>
<div>
<p appSubtitle>This is the first paragraph</p>
<p appSubtitle>This is the second paragraph</p>
<p appSubtitle>This is the third paragraph</p>
</div>
Taking it a step further, let us try to change the colors on the element such that as we hover. The color changes from green to red and comes right back after your mouse leaves.
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
@Directive({
selector: '[appSubtitle]'
})
export class SubtitleDirective {
constructor(private _element: ElementRef, private _renderer: Renderer2) { }
@HostListener('mouseenter') onHover(){
this._renderer.setStyle(this._element.nativeElement, 'transition', '0.5s');
this._renderer.setStyle(this._element.nativeElement, 'background-color', 'red')
}
@HostListener('mouseleave') onLeave(){
this._renderer.setStyle(this._element.nativeElement, 'transition', '0.5s');
this._renderer.setStyle(this._element.nativeElement, 'background-color', '#4CAF50')
}
}
We brought in the element reference class so we can access the native HTML element and change the style easily.
You have seen one good way to listen to and respond to events in the DOM, you have also seen various use cases and how it is used. I hope you begin to use this decorator in your workflows, especially for projects where you work in teams and in various components within one repository. Happy hacking!
Nwose Lotanna Victor is a web technology enthusiast who documents his learning process with technical articles and tutorials. He is a freelance frontend web developer based in Lagos, Nigeria. Passionate about inclusion, community-building and movies in Africa, he enjoys learning new things and traveling.