Ionic 4 + Angular 7: Checking whether the generic parent of a component is the active page

There’s no straightforward way yet in getting the parent component of a component via dependency injection without knowing the type of the parent component. This poses a problem if you want your component consumed by many different types of parent components.

A common scenario where this problem occurs is an Ionic 4 app with several pages that use some component. Each page is of its own type (HomePage, HelpPage, etc.) so it is cumbersome to use the following dependency injection methods to try to figure out what the parent component is:

@Component({
  selector: 'child-component'
})
export class ChildComponent {
  constructor(
    router: IonRouterOutlet,
    @Optional @SkipSelf parentHomePage: HomePage,
    @Optional @SkipSelf parentHelpPage: HelpPage,
    /* etc. for every parent component that consumes ChildComponent */
  ) {    
    if (router.component === parentHomePage 
      || router.component === parentHelpPage
      /* etc. for every possible consuming parent component */)
      console.log('ChildComponent is on the active page!');
  }
}

The obvious issue is that for every new parent component that consumes your component, you’ll have to add that to the list of @Optional dependencies. As your project grows, the constructor and other code in your child component starts to get unwieldy.

The workaround:

For any page that plans on consuming ChildComponent, have it extend a common abstract class.

Define the abstract class:

export abstract class ChildComponentContainer {
}

In HomePage, HelpPage, etc. or any component that will contain the ChildComponent, have it extend this class, and create a provider representing the abstract class that will inject itself. This allows any component that depends on ChildComponentContainer in its constructor to get this parent component:

@Component({
  selector: 'app-home',
  providers: [
    {
      provide: ChildComponentContainer, useExisting: forwardRef(() => HomePage)
    }
  ]
})
export class HomePage extends ChildComponentContainer {
  /* ... */
}

Now, your ChildComponent can simply have a single dependency, ChildComponentContainer, to get the parent component. While not strictly generic (parents are ChildComponentContainers), it will allow you to get the parent component without having to worry about the exact type, thus avoiding having to list every single possible parent component in the constructor.

We can modify the original code now to check whether the parent component is the active page in the router stack (and thus know whether ChildComponent is active too!):

@Component({
  selector: 'child-component'
})
export class ChildComponent {
  constructor(
    router: IonRouterOutlet,
    parentComponent: ChildComponentContainer
  ) {    
    if (router.component === parentComponent)
      console.log('ChildComponent is on the active page!');
  }
}

*     *     *

If you found this article helpful, please consider a donation or leave a comment. Thanks!

0 thoughts on “Ionic 4 + Angular 7: Checking whether the generic parent of a component is the active page”

Leave a Reply

Your email address will not be published. Required fields are marked *