Angular2 router, get route data from url, to display breadcrumbs

I am usingangular2 router.

To draw the breadcrumb of an url, lets say site.com/a/b/c/15 I do the following:

  1. Get the route ofsite.com/a/b/c/15and get the pretty name associated to the route
  2. Get the route ofsite.com/a/b/cand get the pretty name associated to the route
  3. Get the route ofsite.com/a/band get the pretty name associated to the route
  4. Get the route ofsite.com/aand get the pretty name associated to the route

So lets say I do have the following routes:

{ path: 'a', component: A, data:{prettyName: 'I am A'}}
{ path: 'b', component: B, data:{prettyName: 'I am B'}},
{ path: 'c', component: C, data:{prettyName: 'I am C'}},

The result of my process would be an array containing{"I am C", "I am B", "I am C"}and thanks to that I can display a nice breadcrumb"I am A > I am B > I am C"that explains the current route.

This use to work with the router-deprecated doing

this.router.recognize(url).then((instruction) => {
    instruction.component.routeData.get('prettyName') // Would return 'I am ..'

However now; with the last router I am not able to process this recognize logic anymore.

How to get the route data associated to an url ?

Updated for RC5

Instead of starting with the current URL and trying to get the routes from the URL, you can get all of the activated routes (associated with the primary outlet) from theRouterState:

After the end of each successful navigation lifecycle, the router builds a tree ofActivatedRoutes, which make up the current state of the router. We can access the currentRouterStatefrom anywhere in our application using theRouterservice and therouterStateproperty.

The router state provides us with methods to traverse up and down the route tree from any activated route to get information we may need from parent, child and sibling routes. --reference

Subscribe to router events, then, after eachNavigationEndevent, walk down the tree ofActivatedRoutes from theroot:

import { Component } from [email protected]/core';
import { Router, ActivatedRoute, NavigationEnd } from [email protected]/router';
import 'rxjs/add/operator/filter';

@Component({
  selector: 'breadcrumbs',
  template: `
  <div>
    breadcrumbs: 
    <span *ngFor="let breadcrumb of breadcrumbs; let last = last">
      <a [routerLink]="breadcrumb.url">{{breadcrumb.label}}</a>
      <span *ngIf="!last">></span>
    </span>
  </div>`
})
export class BreadcrumbsComponent {
  breadcrumbs: Array<Object>;
  constructor(private router:Router, private route:ActivatedRoute) {}
  ngOnInit() {
    this.router.events
      .filter(event => event instanceof NavigationEnd)
      .subscribe(event => {  // note, we don't use event
        this.breadcrumbs = [];
        let currentRoute = this.route.root,
            url = '';
        do {
          let childrenRoutes = currentRoute.children;
          currentRoute = null;
          childrenRoutes.forEach(route => {
            if(route.outlet === 'primary') {
              let routeSnapshot = route.snapshot;
              console.log('snapshot:', routeSnapshot)
              url += '/' + routeSnapshot.url.map(segment => segment.path).join('/');
              this.breadcrumbs.push({ 
                label: route.snapshot.data.breadcrumb,
                url:   url });
              currentRoute = route;
            }
          })
        } while(currentRoute);
      })
  }
}

Routes look like this:

{ path: '', component: HomeComponent, data: {breadcrumb: 'home'}}

Plunker- RC.5, router 3.0.0-rc.1


See alsohttp://stackoverflow.com/a/38310404/215945for a similar solution.

So far, the most feasable solution is (done):

  • Make the routes export/importable
  • Get the current url update from router.events subscribe
  • On url change, loop on the routes's path, see if the pattern match the url
  • If the patter match the url, get the data from the matching route

Pros: works

Cons: redoing url-route recognition manuall without using the ng2 router one

What Others Are Reading