How to access route params from parent routes in Angular

If you've used the Angular router, you might have run into this problem. When you have a tree of routes, you might need to access route parameters from a parent inside a child.

How to access route params from parent routes in Angular
Photo by Milan Seitler / Unsplash

If you've used the Angular router, you might have run into this problem. When you have a tree of routes, you might need to access route parameters from a parent inside a child.

Let's take this route configuration as an example.

const routes: Routes = [
  {
    path: "grandpa/:grandpaName",
    component: GrandpaComponent,
    children: [
      {
        path: "mom/:momName",
        component: MomComponent,
        children: [
          {
            path: "child/:childName",
            component: ChildComponent
          }
        ]
      }
    ]
  }
];

Typically, when you want to get a route parameter, you'd use the ActivatedRoute like so:

export class ChildComponent {
  constructor(private route: ActivatedRoute) {
    this.route.paramMap.subscribe(map => {
        const name = map.get('childName');
    });
  }
}

But what if you want to access the grandpaName parameter from inside the ChildComponent? If you use the code above, you'll see that it is not included in the paramMap.

Using paramsInheritanceStrategy

One way to be able to access the ancestors' parameters is using the paramsInheritanceStrategy property.

When you're importing the RouterModule, you can configure it with an ExtraOptions object. Particularly, you can set paramsInheritanceStrategy to "always" so that the parameters from the ancestors are inherited by the children.

RouterModule.forRoot(routes, { paramsInheritanceStrategy: "always" })

You might have one of three problems with this solution:

  • You can't use paramsInheritanceStrategy
  • You want to access all the parameters in the route
  • You want to access the parameters without an ActivatedRoute (for example from a service)
collectRouteParams(router: Router) {
  let params = {};
  let stack: ActivatedRouteSnapshot[] = [router.routerState.snapshot.root];

  while(stack.length > 0) {
    const route = stack.pop();
    params = {...params, ...route.params};
    stack.push(...route.children);
  }

  return params;
}

This function performs a breadth-first search of the router state tree and stores the parameters of each ActivatedRoute in the params object.

Wrapping up

Here we saw two ways of accessing route parameters defined outside the current component.

  • paramsInheritanceStrategy = "always" allows you to access a route parameter from an ancestor route;
  • collectRouteParams is a function that iterates through the activated routes in the router and saves the parameters from each route in the tree.

If paramsInheritanceStrategy serves your purpose, use it. It should be more performant than going through the whole route tree (although the impact is probably small).

If you need access to route parameters outside the ancestor path or if you can't change the paramsInheritanceStrategy, you can use the collectRouteParams function.

These made my life much easier when dealing with the router. I hope this was useful, as it's something that I felt a bit "out of reach".

If you have any questions or suggestions, you can reach me on Twitter @pedronavelopes.

Thanks for reading!