JoAMoS
JoAMoS

Reputation: 1519

Angular merge parent route data with current route

I would like to have an easy way to access all the route data of the parents at the current child route, this seems like it would be a common task am I missing something built into angular?

Example

const routes: Routes = [
  {
    path: '',
    component: WrapperComponent,
    data: {
      prop1: 'abc',
    },
    children: [
      {
        path: '',
        component: HomeComponent,
        data: {
          prop2: '1',
          prop3: 'Some other data',
        },
      },
      {
        path: 'welcome',
        data: {
          prop1: 'efg',
          prop2: 'my cool prop',
        },
      },
];

My goal would be some sort of property of the activated route that returns the merged route data so if at:

/ - the route data would be

{
   prop1: 'abc',
   prop2: '1',
   prop3: 'Some other data',
}

/welcome - the route data would be

{
   prop1: 'efg',
   prop2: 'my cool prop',
}

I have implemented this with the following code but I bet someone better with observables could write this better.

this.router.events  // private router: Router,
  .pipe(
    filter((event) => event instanceof NavigationEnd),
    map(() => this.activatedRoute),
    map((route) => {
      let data: any = {};
      while (route.firstChild) {
        data = { ...data, ...route.firstChild.snapshot.data };
        route = route.firstChild;
      }
      return data;
    }),
  ).subscribe((e) => console.log(e));

Does this functionality already exist in angular?

Upvotes: 4

Views: 1434

Answers (2)

user1
user1

Reputation: 1135

I believe this should work:

constructor(router: Router) {
  router.events.pipe(
    filter(e => e instanceof ActivationEnd),
    buffer(router.events.pipe(filter(e => e instanceof NavigationEnd), debounceTime(0))),
    map((events: ActivationEnd[]) => events.reduce((acc, curr) => ({ ...acc, ...curr.snapshot.data }), {}))
  );
}
  1. Filter out for the ActivationEnd events (we have the route snapshots there so we can get the data for the individual routes from them)

  2. buffer them until we've gotten all the NavigationEnd events for the current stack

  3. reduce over all the buffered events and collect the data inside one object (collisions are not handled)

Upvotes: 1

Brozorec
Brozorec

Reputation: 1183

I think it's possible to do that by using paramsInheritanceStrategy: 'always' when you set RouterModule:

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { paramsInheritanceStrategy: 'always' })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Upvotes: 6

Related Questions