Angular 2 new Router: How to get router parameters of a child component?

The child parameters are associated/stored with the child ActivatedRoute. They are not available on the parent's ActivatedRoute. So you first need to get the child's ActivatedRoute using getter firstChild or children.

Then, the parent can either subscribe to child parameter changes:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute }               from '@angular/router';
import { Subscription }                 from 'rxjs/Subscription';

export class ParentComponent implements OnInit, OnDestroy {
   private sub: Subscription;
   constructor(private route: ActivatedRoute) {}
   ngOnInit() {
      this.sub = this.route.firstChild.params.subscribe(
        params => console.log(params.id));
   }
   ngOnDestroy() {
      this.sub.unsubscribe();
   }
}

or it can get a snapshot of the child parameters:

import { Component }      from '@angular/core';
import { ActivatedRoute } from '@angular/router';

export class ParentComponent {
   constructor(private route: ActivatedRoute) {}
   someMethod() {
      console.log(this.route.firstChild.snapshot.params.id);
   }
}

If you want to get all of the children (e.g., if you have multiple outlets), use ActivatedRoute.children or ActivatedRouteSnapshot.children to get an array of child ActivatedRoutes or child ActivatedRouteShapshots.


It's super easy to get the child parameters via ActivatedRoute, however you can quickly run into issues if you change the current child.

First a couple notes:

  • activatedRoute.firstChild property is an ActivatedRoute instance and NOT an observable.
  • Also note that activatedRoute.paramMap is an observable.

Here's how you can run into problems:

  • Consider a component with two child routes - and corresponding components - where only one is shown at a time (for example a tabbed interface).
  • If you access firstChild.paramMap inside your ngOnInit handler you'll be able to subscribe to it and monitor the parameters as they change. This will look and work just fine.
  • If you switch to the second tab and then back to the first everything will break. This is because you originally subscribed paramMap on an ActivatedRoute instance that doesn't exist anymore.
  • Important: This is only a problem if you're trying to access the child's paramMap. If you're trying to access your 'own' paramMap, or the child component also injects paramMap then everything will be fine.

The cleanest solution to this I've found is as follows:

Note: First inject router: Router in addition to route: ActivatedRoute.

const firstChildParams$ = this.router.events.pipe(filter(e => e instanceof NavigationEnd),
                                                  startWith(undefined),
                                                  switchMap(e => this.route.firstChild!.paramMap));

What this does is listens for only NavigationEnd events, after which a new firstChild will be available. By using switchMap you don't need to worry about unsubscribing to old redundant maps. Also not that the actual value of the navigation event is never used, and startWith is needed to be able to immediately handle parameters the first time.

I've been collecting helpful things like this into a RouterHelperService that I can inject anywhere, and not have to remember all this craziness.


Some day I may suggest that there should be an observable equivalent of firstChild, then this wouldn't be a problem. However it would perhaps introduce even more confusion in other scenarios!


The ActivatedRoute has getters to access its parent/child route information.

In order to access the first child route from the parent, you would use:

this.route.firstChild.params

If you wanted all the child routes you would use the children property. This returns an array of ActivatedRoute

this.route.children

If you were in a child route and needed parameters from the parent:

this.route.parent.params