In the latest version of @angular/router
3.0.0-rc.1
The way you get the parameters from a URL/route changed.
Based on this documentation yo
By using this.activatedRoute.snapshot.firstChild.params
this.router.events.subscribe(event => {
if (event instanceof RoutesRecognized) {
// let strId = event.state.root.firstChild.children[0].data;
let a = event.state.root.firstChild.children.map((route) => {
while (route.firstChild) {
route = route.firstChild;
}
return route;
});
console.log('Title', a[0].data.title);
this.meta.updateTitle(a[0].data.title);
}
if (event instanceof NavigationEnd) {
(<any>window).gtag('config', this.googleAnalyticsCode, {
'page_title' : this.titleService.getTitle(),
'page_path': event.urlAfterRedirects
});
}
});
this.route.snapshot.paramMap.get('id');
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.
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
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.activatedRoute.paramMap
is an observable.Here's how you can run into problems:
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.paramMap
on an ActivatedRoute instance that doesn't exist anymore.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!