Error pushing a child onto the nav controller via an abstract parent class

Hey there. I’m assembling an app that uses a parent abstract class to handle navigation through to various child page types. Consider the following (simplified) example:

export abstract class BasicPage {
  public pages: PageService;
  public navCtrl: NavController;

  goToPage(id: string) {
    let page = this.pages.getPageByID(id);
    if (page.type === 'bluePage') this.navCtrl.push(BluePage, { id: id });
    if (page.type === 'redPage') this.navCtrl.push(RedPage, { id: id });
  }
}
@IonicPage()
@Component({
  selector: 'page-blue',
  templateUrl: 'blue.html',
})
export class BluePage extends BasicPage {
  constructor(public navCtrl: NavController, public pages: PageService) {
    super();
  }
}

The goal of this is to create a very simple abstract class from which the child pages can navigate to any other page type. For example, if goToPage() is called from the red OR blue page, the parent class BasicPage will correctly determine which page to go to based on the type.

This should work in theory. However, for some reason, I am getting the following error: “Object prototype may only be an Object or null: undefined”. This is fixed by either removing the inheritance in the BluePage, or removing any lines that reference RedPage or BluePage in the BasicPage parent class. Obviously, this defeats the purpose of the inheritance.

I’m sure this is something simple I’m missing based on how inheritance works in TypeScript, but I can’t figure it out or think of an alternative. Abstract classes are my preferred way for handling repetitive code. How would you guys go about fixing this?

I’m not that advanced with ionic 2+ or much new versions of angular. But, it seems similar to the issues I was having with the native page transitions plugin.

What I did I set the page in the app.modules.ts (going off memory here sorry if it’s a little bleak);

I set the providers and whatever as needed then after that I declared which pages to where. If my page doesn’t exist it’ll default itself.

Example I could be like (click)=“loadPage(‘blue’)” and it’d transition into the blue page unless I didn’t define it. I was getting lots of object errors too because I didn’t set it up correctly but in the end I had to set the pages: any; and put it in the constructor and all that good stuff.

So when you load your page in your function or whatever it’s called on the new angular:

loadPage(page){
//then push the page 
this.navCtrl.push(page);
}

It was something like that.

Good luck.

If you don’t get any better answers, and are willing to listen to an old opinionated curmudgeon, I am not a fan of inheritance. I am especially not a fan of inheritance in JavaScript, which has zero OO language support. It makes apps hard to read, maintain, and test, because functionality is distributed haphazardly everywhere.

That being said, if you insist on going down this road, I suspect your problem is caused by circular dependency. Two potential ways of resolving it are using forwardRef and switching to lazy page loading, in which case you will be interacting with the navigation system using strings and the problem should organically go away.