App.getComponent('nav') undefined in MyApp class constructor


#1
export class MyApp {
  root: Type = WelcomePage;
	app:IonicApp;

	constructor(app: IonicApp, events: Events, platform: Platform, authService:AuthService) {
		this.app = app;

		let t = setTimeout(() => {
			let nav = this.app.getComponent('nav');
			console.log(nav);
		}, 100);


This code successfully gets the ‘nav’ component after a 100 ms delay. But if I remove the timeout, the getComponent call returns undefined. Using a timeout feels hackish, is there a better way to wait until the ion-nav component has been rendered before getting the component?


#2

I have a similar issue with ionic 2 beta.2

Uncaught EXCEPTION: Error during evaluation of "click"
ORIGINAL EXCEPTION: TypeError: Cannot read property 'setRoot' of undefined
ORIGINAL STACKTRACE:
TypeError: Cannot read property 'setRoot' of undefinedat MyApp.openHomePage 
    at AbstractChangeDetector.ChangeDetector_MyApp_0.handleEventInternal (viewFactory_MyApp:129:37)
    at AbstractChangeDetector.handleEvent (http://localhost:8100/build/js/app.bundle.js:14026:30)
    at AppView.triggerEventHandlers (http://localhost:8100/build/js/app.bundle.js:18333:37)
    at eval (viewFactory_MyApp:275:98)

My code is below

import {App, IonicApp, Platform, MenuController, Menu, Toolbar} from 'ionic-angular';
import {HomePage} from './pages/home/home';

@App({
  template: `
    <ion-menu persistent="true" [content]="content">
      <ion-toolbar>
        <ion-title>Pages</ion-title>
      </ion-toolbar>
      <ion-content>
        <ion-list>
          <button ion-item (click)="openHomePage()">
            Home
          </button>
        </ion-list>
      </ion-content>
    </ion-menu>

    <ion-nav #content [root]="rootPage"></ion-nav>
  `,
  providers: [],
  config: {}, // http://ionicframework.com/docs/v2/api/config/Config/
  directives: [Menu, Toolbar]
})
export class MyApp {
  rootPage: any;

  constructor(
    public app: IonicApp,
    public platform: Platform,
    public menu: MenuController) {

    this.rootPage = HomePage;

    this.platform.ready().then(() => {

    });
  }

  openHomePage() {
    this.menu.close();
    let nav = this.app.getComponent('nav');
    nav.setRoot(this.rootPage);
  }
}


#3

@jasonwaters It is all about correct approach.

In constructor platform isn’t yet ready so even your code with timeout will not work.

Here is how code should looks like:

export class GCloud {
    platform:Platform;
    pages:{title:string; component:any}[];
    rootPage:any;
    app:IonicApp;
    nav:NavController;

    constructor(app:IonicApp,
                platform:Platform) {
        this.platform = platform;
        this.app = app;
    }

    ngOnInit() {
        this.initializeApp();
        this.pages = [
            {title: 'Dashboard', component: DashboardPage}
        ];

        this.rootPage = DashboardPage;
    }

    initializeApp() {
        var self = this;
        this.platform.ready().then(() => {

            StatusBar.styleDefault();

            var nav:NavController = this.app.getComponent("nav");
            this.nav = nav;

            if (!hasAuthToken())
                nav.setRoot(LoginPage);
        });
    }

    openPage(page) {
        // Reset the content nav to have just this page
        // we wouldn't want the back button to show in this scenario
        this.nav.setRoot(page.component);
    }
}

Hope this helps :wink: