2

The Angular(2+) router has an events property that is a rxjs subject.

Once subscribed, you are able to listen for events like:

router.events.subscribe((event: Event) => { console.log(event) });

but the problem is you have no way to obtain the event type since it listens for all events. A hacky solution is you can inspect the constructor name of the event like:

router.events.subscribe((event: Event) => {
  if(event.constructor.name === 'NavigationStart') {
    loadingService.start();
  } else if(event.constructor.name === 'NavigationEnd') {
    loadingService.complete();
    drawerService.destroyAll();
  }
});

I was curious if there was a better way to accomplish this?

0

3 Answers 3

1

Event is only the base class.

The concrete event values are one of

  • NavigationStart
  • NavigationEnd
  • NavigationCancel
  • NavigationError
  • RoutesRecognized

You can for example use:

constructor(router:Router) {
  router.events
    .filter(event => event instanceof NavigationStart)
    .subscribe((event:NavigationStart) => {
      // You only receive NavigationStart events
    });

See also How to detect a route change in Angular 2?

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks so much! PR'd this back to the docs too! github.com/angular/angular/pull/15142
The best form of contributing :)
0

If you install @bespunky/angular-zen you could extend RouteAware and create an event handler method named onNavigationEnd like so:

import { Component                                        } from '@angular/core';
import { NavigationStart, NavigationEnd, RoutesRecognized } from '@angular/router';
import { RouteAware                                       } from '@bespunky/angular-zen/router-x';

@Component({
    selector   : 'app-demo',
    templateUrl: './demo.component.html',
    styleUrls  : ['./demo.component.css']
})
export class DemoComponent extends RouteAware
{
    // ✨ Any router event can have a handler method.
    // See https://angular.io/guide/router#router-events for a complete list of angular's router events.

    // ✨ Use `this.router` to access the router
    // ✨ Use `this.route` to access the activated route
    // ✨ Use `this.componentBus` to access the RouterOutletComponentBus service
    
    protected onNavigationStart(event: NavigationStart): void
    {
        console.log(`Navigation started for: ${event.url}`);
    }

    protected onRoutesRecognized(event: RoutesRecognized): void
    {
        console.log('Recognized routes.');
    }
    
    protected onNavigationEnd(event: NavigationEnd): void
    {
        console.log(`Navigation ended for: ${event.url}`);
    }
}

Here's a live example

The library is open source and you can install it like this:

npm install @bespunky/angular-zen

Comments

0

Here's a simple little method for testing purposes that will log out each possible event name as they happen. There can be a lot that happen fast, so I recommend also going to your DevTools "Network" tab and enabling throttling to something like DSL speeds so you can see these events happen at an easier to understand speed.

this.router.events.subscribe((ev) => {
  let navType = 'unknown!';
  if (ev instanceof NavigationStart) {
    navType = 'NavigationStart';
  } else if (ev instanceof RouteConfigLoadStart) {
    navType = 'RouteConfigLoadStart';
  } else if (ev instanceof RouteConfigLoadEnd) {
    navType = 'RouteConfigLoadEnd';
  } else if (ev instanceof RoutesRecognized) {
    navType = 'RoutesRecognized';
  } else if (ev instanceof GuardsCheckStart) {
    navType = 'GuardsCheckStart';
  } else if (ev instanceof ChildActivationStart) {
    navType = 'ChildActivationStart';
  } else if (ev instanceof ActivationStart) {
    navType = 'ActivationStart';
  } else if (ev instanceof GuardsCheckEnd) {
    navType = 'GuardsCheckEnd';
  } else if (ev instanceof ResolveStart) {
    navType = 'ResolveStart';
  } else if (ev instanceof ResolveEnd) {
    navType = 'ResolveEnd';
  } else if (ev instanceof ChildActivationEnd) {
    navType = 'ChildActivationEnd';
  } else if (ev instanceof ActivationEnd) {
    navType = 'ActivationEnd';
  } else if (ev instanceof NavigationEnd) {
    navType = 'NavigationEnd';
  } else if (ev instanceof NavigationCancel) {
    navType = 'NavigationCancel';
  } else if (ev instanceof NavigationError) {
    navType = 'NavigationError';
  } else if (ev instanceof NavigationSkipped) {
    navType = 'NavigationSkipped';
  } else if (ev instanceof Scroll) {
    navType = 'Scroll';
  }
  console.log(navType, ev);
});

In general though for most simple applications you only need to see when the navigation has ended, like this:

this.router.events.subscribe((ev) => {
  let navType = 'unknown!';
  if (ev instanceof NavigationEnd) {
    //Do stuff here
  }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.