title: Is there better way to get ancestor route params in Angular2?
body: <p>I need to get param from route which is not parent and not even grand-parent, it's simply somewhere above, along the path to root. I am aware of approaches like shown in <a href="https://stackoverflow.com/questions/34500147/angular-2-getting-routeparams-from-parent-component/37973553">Angular 2: getting RouteParams from parent component</a> or through shared service but situation which I put myself into (at least I think so) makes those not well suited for it. So here is what I got:</p>
  
  <p>I have lazily loaded sub-module which needs <code>id</code> from parent context. Situation more or less looks in routing configuration like this :</p>
  
  <pre><code>// Parent/outer module routing
  const outerRoutes: Routes = [
      {
          path: 'container/:containerId',
          component: ContainerComponent,
          children: [
              { path: 'model', loadChildren: 'app/container/model/model.module#ModelModule' },
              { path: '', component: ContainerDetailsComponent }
          ]
      }
  ];
  
  // Child/inner module routing
  const innerRoutes: Routes = [
      {
          path: '',
          component: ModelComponent,
          children: [
              { path: ':id', component: ModelDetailsComponent },
              { path: '', component: ModelsComponent }
          ]
      }
  ];
  </code></pre>
  
  <p><code>ModelsComponent</code> needs to load all <code>Model</code> instances belonging to given <code>Container</code>. So I decided to go through <code>.parent</code> approach but my teeth started to hurt after writing 2nd <code>.parent</code> and there was still 3rd to come: </p>
  
  <pre><code>this.route.parent.parent.parent.params
    .switchMap((params: Params) =&gt; this.modelService.getAllBelongingTo(params['containerId']))
    .subscribe(
      (models: Model[]) =&gt; this.models = models,
      error =&gt; this.raceEvent = null
    );
  </code></pre>
  
  <p>Shared service is somehow an option but due to the fact that child module is lazily loaded I would have to put it in core module making it quite global (which I don't like).</p>
  
  <p>After a bit of struggling I came to following piece of code, which simply takes all <code>ActivatedRoute</code> up to the root, combines them, does lookup for param and consumes it. I don't like it as in my opinion it too complex , unreadable and stinks from a mile (or in other words is gory as heck) but works and I don't have to take care whether nesting changes. I simply have to make sure that <code>:containerId</code> is somewhere up there on the path to root.</p>
  
  <pre><code>import { Component, OnInit } from '@angular/core';
  import { ActivatedRoute, Params } from '@angular/router';
  import { Observable } from 'rxjs/Observable';
  
  import { Model } from './model';
  import { ModelService } from './model.service';
  
  @Component({
      ...
  })
  export class ModelsComponent implements OnInit {
      models: Model[];
  
      constructor(
          private route: ActivatedRoute,
          private modelService: ModelService) { }
  
      ngOnInit() {
          const paramsArr = this.route.pathFromRoot.map(route =&gt; route.params);
  
          Observable.combineLatest(paramsArr)
              .switchMap(arrOfParams =&gt; {
                  const params = arrOfParams.find(p =&gt; p['containerId'] !== undefined),
                        id = params &amp;&amp; params['containerId'];
                  return id ? this.modelService.getAllBelongingTo(id) : [];
              })
              .subscribe(
                  (models: Model[]) =&gt; {
                      // yay! we got sth
                      this.models = models;
                  },
                  error =&gt; {
                      // handle big nono
                  }
              );
      }
  }
  </code></pre>
  
  <p>Is there a better way to handle depicted situation?</p>