Angular 2 – Detecting Route Changes

Rick HerrmannI ran into a scenario the other day in an Angular 2 app I am working on where I needed to show the same page/route, but with different data and parameters. Without getting into the specifics of my app, the scenario was analogous to this:

I am viewing a page that shows customer contact details. The route pattern could be something like “/customers/:customerId/contact/:contactId”. On the customer contact detail page, we also show a list of links for other contacts with the same customer.

Clicking on a name from the list of other contacts should show the contact details for that person. So while the current route is “/customers/1/contact/11”, I want to navigate to “/customers/1/contacts/19”.

What I found was that the url did change as expected, but my ngOnit component event did not fire. Since this was where I was loading the data for the requested contact – the page data did not change and still showed the previous contact.

So – why was this happening? After doing some investigation in the Angular 2 docs, I learned that when a route change does not result in a different component being loaded, the current component does not get unloaded. This explained why the ngOnit was not firing after the route change – the component was not unloaded/reloaded.

Rewind back to a few months ago when I was working on my first Angular 2 project. At the point I was working on a component that needed to read the route parameters, I found that activeRoute.params was actually an Observable, not just a dictionary of parameter name/value pairs. At the time I was just getting my head around using Observables for making service calls and could see the power that they provided. But Observables for route params? What was the point? There was a shortcut to get to the route params without subscribing to an Observable:

this.route.snapshot.data['contactId']

So in what scenario would someone want to subscribe to the activeRoute.params Observable? It turns out the scenario I described above is exactly what the params Observable is for.

By changing from:

this.contactId = this.activeRoute.params['contactId']

to this, everything worked fine. By subscribing to the params Observable, when the route parameters change we can re-initialize the component even though it does not actually reload.

this.activeRoute.params.subscribe(
  params => {
    this.contactId = +params['contactId'];
    this.initializeComponent();
  }
);

private initializeComponent() {
// do the stuff you would have done in ngOnit...
}

Problem solved!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s