Search code examples
angularangular-routingangular-activatedroute

Angular, get parent route component


I am building an Angular 7 app. In this app I got nested routes. I want to be able to detect what component the parent route is using. I found a way of doing it locally but this does not work on production (output is different).

I use this method:

   checkIfChild() {
    this.sub = this.route.parent.params.subscribe(params => {
      if (params['id']) {
        this.parentId = params['id'];
        if (this.route.parent.component['name'] === 'ProjectShowComponent') {
          this.parentType = 'Project';
        } else if (this.route.parent.component['name'] === 'CompanyShowComponent') {
          this.parentType = 'Company';
        } else if (this.route.parent.component['name'] === 'ContactShowComponent') {
          this.parentType = 'User';
        }
      }
    });
  }

The method, this.route.parent.component['name'], outputs the name locally but just the letter T on production.

I get this message instead

TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context.

What is the right way of detecting what parent route has activated the child route so that I can act on it?


Solution

  • Personally, I would drop the direct coupling to the component instance and instead use the data property of the route, considering that:

    • You arent interacting with the component instance in any way.
    • You map the component instance type to a static value.

    Assuming the following routes definition:

    const routes: Routes = [
      {
        path: 'production',
        component: ProductionParent,
        data: {parentRoute :'Production'},
        children: [{path: '', component: Child}] 
      },
      {
        path: 'system',
        component: SystemParent,
        data: {parentRoute :'System'},
        children: [{path: '', component: Child}] 
      }
    ];
    
    @Component({})
    export class ProductionParent{}
    
    @Component({})
    export class SystemParent{}
    
    @Component({})
    export class Child implements OnInit, OnDestroy {
      private parentSub = Subscription.EMPTY;
      parentRoute :string;
    
    
      constructor(private readonly route: ActivatedRoute){}
    
      ngOnInit(){
        this.trackParent();
      }
    
      ngOnDestroy(){
       this.parentSub.unsubscribe();
      }
    
      private trackParent(){
        this.parentSub = this.route.parent
                            .data
                            .subscribe(data => this.parentRoute = data.parentRoute || 'unknown');
      }
    }
    

    This can most likely be implemented in other ways, but this is the first pragmatic approach that came to my mind. Hope it helps.