Introduction

Are you looking to add interactivity to your Angular application based on user actions such as scrolling? In this blog post, we will explore how to use Angular’s HostListener to respond to events like click, scroll, mousehover etc.
Whether you want to trigger animations, load more content, or perform specific actions when a user scrolls, using HostListener in Angular can help you achieve the desired functionality.
Join us as we dive into an example of implementing HostListener for scroll events in an Angular application.

Event Handling

Suppose you want to listen for an event or handle some event such as a mouse click on an angular component, then how would you do it.

One way is to add a javascript event listener but that would be on a particular element such as a button in HTML template as shown below.

<mycomponent>
   <button onclick="handle();">Click</button>
</mycomponent>

and corresponding event handler in component typescript class as

handle(): void {
  // click event handler code
}

For binding an event to the entire page or component, you need to do similar stuff on body or component root tag using javascript document or window objects.
This is also one way of handling events but not something that you would see in angular applications.

HostListener working

For handling an event on angular components or directives, HostListener is used. This is a directive provided by angular and enables you to write handler methods for events.

These handler methods are automatically invoked by angular when the event for which they are configured happens.

For using HostListener, perform the following steps.

1. Create a method as would normally do in component typescript class. This method will contain event handling logic.
2. Apply @HostListener() directive over this method along with the name of event to handle. Event name will be in string format enclosed between parenthesis.

HostListener belongs to the package @angular/core.

When the event for which HostListener is configured occurs inside the component template, method annotated with @HostListener is invoked by angular.

Angular HostListener example

Below is an example of HostListener for handling a click event on an angular component following the steps above.

@Component({
   selector:'mycomponent'
})
export class MyComponent {

   @HostListener('click')
   clickHandler() {
      alert('Component clicked');
   } 
}

Notice the name of event after @HostListener directive. This means that we have added a click event handler for our component.

Suppose the HTML template for this component is

<mycomponent>
   <div>This is custom component</div>
   <div>This component listens for click events</div>
</mycomponent>

Now whenever you click anywhere within this component area, the method with @HostListener directive(clickHandler() in this case) will automatically be called or invoked.

Events outside the component

By default, @HostListener will listen to the events arising in the component where it is written.
This means that a method with @HostListener directive will get called only if you click inside the component. For clicks outside the component, it will not be called.

It may happen that you want to listen to an event arising anywhere on the web page. This is also possible with HostListener as shown below.

@HostListener('window:scroll')
onScroll() {
   alert('Page scrolled');
}

You need to write the scope before event name. In this case, it is window:.
Above example will detect a scroll event and invoke this method when the page is scrolled. This method may be placed in any component and will be invoked on page scroll.

@HostListener supports window, document and body global objects. If these are not written before the event name, then the default scope is component.

Passing arguments

It is often required to pass arguments to the event handler method. Most common argument is the event object itself.
Arguments are passed as an array after the name of event in @HostListener directive as shown below.

@HostListener('click', ['$event'])
onClick(event: any) {
  // get the clicked element
  console.log(event.target);
}

You also need to declare an argument in the method definition which will receive the implicit argument value such as event in this case.
The name $event is significant or reserved when passed in @HostListener and is populated automatically by angular.

If you only want the target element, then you can simply pass $event.target as the implicit argument, it is not necessary to pass the entire event object as shown below.

@HostListener('click', ['$event.target'])
onClick(element: any) {
  // get the clicked element
  console.log(element);
}

You may also pass more than one arguments to the event handler method as shown below.

@HostListener('click', ['"Element Clicked"','$event'])
onClick(message:string, event: any) {
  alert(message)
  // get the clicked element
  console.log(event.target);
}

Note that the string argument is enclosed between quotes.

List of events

HostListener supports all standard javascript events. List of some events is

1. blur
2. change
3. click
4. drag
5. drop
6. focus
7. keydown
8. keypress
9. keyup
10. mouseenter
11. mouseover
12. resize
13. scroll

and many more.

Common error

When using HostListener, you might come across below error.

TypeError: decorator is not a function(…)

This error might arise because of a syntax error while writing the handler function. Thus, if you use it as

@HostListener('keyup')({
onKeyUp(e) {
   console.log(e)
}
});

Here, the function is defined inside the @HostListener directive which is syntactically incorrect.

Conclusion

In conclusion, mastering the Angular HostListener is a critical skill for any developer looking to craft responsive, interactive web applications that can react to user events seamlessly.
With the examples provided in this blog, you’ve seen how HostListener works in real-world scenarios, how to capture events outside the component, and the flexibility of passing arguments to enhance the user experience.
Implementing HostListener not only simplifies your code by avoiding manual event listener management but also gives you powerful control over the DOM events within your Angular applications.
Remember, a well-implemented HostListener can make the difference between a good application and a great one.