Run Code when You Leave Your Angular App

Written by Preston Lamb

Posted on Apr 21, 2021

angular

Getting Started with Deno

Learn how to start using Deno with my brand new course!

Buy the Course

tldr;

We have all seen and likely used the ngOnDestroy lifecycle hook. But did you know it doesn't fire when the browser tab is refreshed or closed or the URL is changed to a new page? What do you do if you need to do some cleanup when the entire Angular app is destroyed? It turns out to not be too hard through the use of a @HostListener.

What's the Problem?

I was recently working on an issue in an app that needed to be resolved by clearing a portion of the localStorage when the Angular app redirected to the authentication server. I figured it would be simple; I would just use ngOnDestroy in the main AppComponent and clear the localStorage item! But it turns out that didn't work. The Angular docs say this about the ngOnDestroy hook:

Called immediately before Angular destroys the directive or component.

Notice it does not say that it is called before the browser destroys the Angular app. So my first stab at solving the problem didn't work. Luckily I found another way that's just as simple to solve this problem.

Using the HostListener

Depending on the amount of time you've used Angular, you may or may not know about the HostListener decorator. This decorator "declares a DOM event to listen for, and provides a handler method to run when that event occurs". In other words, you use this decorator in a component to listen to DOM events and run handler functions when the event fires. This is what you can use to run certain pieces of code when the application is destroyed by the browser (by refresh, or changing to a new site, or whatever the case may be).

The two DOM events that I used to accomplish this were beforeunload and unload. The beforeunload event fires when a window is about to unload its resources. The unload event fires when the window is unloading its content and resources. Depending on your situation, either of these could work. Here is how the HostListener can be used with one of these events:

export class AppComponent implements OnInit {
  @HostListener('window:unload', [ '$event' ])
  unloadHandler(event) {
    // ...
  }

  @HostListener('window:beforeunload', [ '$event' ])
  beforeUnloadHandler(event) {
    // ...
  }
}

With these HostListeners, the functions underneath the decorator will be run when the event fires in the browser. Inside those functions is where you will run the cleanup code.

Conclusion

While there isn't a lifecycle hook for the app being destroyed by the browser, a HostListener and an event to listen to will accomplish the same result. You can use this same method for any event that the browser fires.

Getting Started with Deno

Learn how to start using Deno with my brand new course!

Buy the Course