Angular 5 add event before the route change

Js Lim picture Js Lim · Dec 27, 2017 · Viewed 19.9k times · Source

I'm want to add a alert dialog before the user click on the <a href="..."> link.

There are 2 types of <a> link

  1. Redirect within Angular scope <a routerLink="/path/to/dest">
  2. Redirect outside of Angular app <a href="http://www.somewhere.com" target="_blank">

I want to able to show an alert box when user try to go outside of Angular scope

Alert dialog

I want to apply to all <a> click event (kind like pre-hook)

Any way to achieve this?

Answer

ConnorsFan picture ConnorsFan · Dec 27, 2017

For links to other views of your Angular application, you can implement a CanDeactivate route guard. You will find an example in this stackblitz, for the "Home" page.

The links that navigate outside of the application should trigger the event handler bound to window:beforeunload (shown in HomeViewComponent below). However, its behavior seems to be different in Firefox (a confirmation box is shown) and in Chrome (no confirmation box shown). That event cannot be tested with stackblitz, as far as I can see.


In app.module:

...
import { AppRoutingModule } from './app.routing.module';
import { DeactivateGuard } from './views/home/deactivate-guard';

@NgModule({
  imports: [ 
    AppRoutingModule, 
    ... 
  ],
  providers: [
    DeactivateGuard
  ],
  ...
})

In app.routing.module:

...
import { RouterModule } from '@angular/router';
import { DeactivateGuard } from './views/home/deactivate-guard';

@NgModule({
  imports: [
    RouterModule.forRoot([
      ...
      {
        path: 'home',
        component: HomeViewComponent,
        canDeactivate: [DeactivateGuard]
      },
      ...
    ])
  ],
  exports: [
    RouterModule,
  ],
  ... 
})

In home/deactivate-guard:

import { CanDeactivate } from '@angular/router';
import { HomeViewComponent } from './home.component';

export class DeactivateGuard implements CanDeactivate<HomeViewComponent> {

  canDeactivate(component: HomeViewComponent) {
    return component.canDeactivate();
  }
}

In home.component:

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

@Component({
  ...
})
export class HomeViewComponent {

  @HostListener("window:beforeunload", ["$event"]) unloadHandler(event: Event) {
      event.returnValue = false;
  }

  canDeactivate() {
    return confirm("Do you want to leave?");
  }

  ...
}