3
 @HostListener('window:scroll', ['$event'])
  onScroll(event) {
    // Do something
  }

I have been listening to scroll events in many components. And I am not unsubscribing. Does it cause a problem.

Shilpa J
  • 41
  • 6

1 Answers1

6

Should Host listeners be unsubscribed?

No, there is no need to unsubscribe - host listeners are destroyed when the component they belong to is destroyed

How does Host Listner[sic] work?

To better understand how HostListener works, I recommend reading these helpful docs

When does it get unsubscribed?

When the parent component/directive is destroyed


To illustrate my point, look at this example app :

app.module.ts

import { RouterModule, Routes } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { Test1Component } from './test1/test1.component';
import { Test2Component } from './test2/test2.component';

const routes: Routes = [
  { path: 'test1', component: Test1Component },
  { path: 'test2', component: Test2Component },
  { path: '**', redirectTo: 'test1' }
];


@NgModule({
  declarations: [
    AppComponent,
    Test1Component,
    Test2Component
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(routes)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<h1>host listener example</h1>
<a routerLink="test1">test1</a>
<a routerLink="test2">test2</a>
<router-outlet></router-outlet>
<div>
  <p>some content</p>
  <div style="height:1000px"></div>
  <p>some content down the page</p>
</div>

test1.component.ts

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

@Component({
  selector: 'app-test1',
  templateUrl: './test1.component.html',
  styleUrls: ['./test1.component.css']
})
export class Test1Component implements OnInit {
  constructor() { }

  ngOnInit() { }


  @HostListener('window:scroll', ['$event'])
  onScroll(event) {
    console.log('scroll event in Test1Component', event);
  }
}

test2.component.ts

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

@Component({
  selector: 'app-test2',
  templateUrl: './test2.component.html',
  styleUrls: ['./test2.component.css']
})
export class Test2Component implements OnInit {

  constructor() { }

  ngOnInit() {
  }

  @HostListener('window:scroll', ['$event'])
  onScroll(event) {
    console.log('scroll event in Test2Component', event);
  }

}

The app will default redirect to host:port/test1, rendering TestComponent1. When a scroll event happens, it will log to the console 'scroll event in Test1Component' and information about the event. If you change the url to host:port/test2, it will destroy the test1component (along with its @HostListeners) and render the test2component. Now, when a scroll event happens, it will log to the console 'scroll event in Test2Component' and information about the event. Notice how it does not log 'scroll event in Test1Component' because that @HostListener was destroyed when its parent component (Test1Component) was destroyed.

Vega
  • 27,856
  • 27
  • 95
  • 103
abatis
  • 81
  • 1
  • 5