Ion-menu navCtrl: undefined

Hi all ! Could anyone help please ! I want to add to the menu default page as ionic2 generate … like AccountPage, but have message navCtrl: undefined and when I click inside Menu on Account - nothing happend.

<ion-menu [content]="content" side="right" persistent="true">
  <ion-toolbar>
    <ion-title>Menu</ion-title>
  </ion-toolbar>
  <ion-content>
    <ion-list>
      <button ion-item *ngFor="let value of listPages" (click)="openPage(value)">{{value.title}}</button>
    </ion-list>
  </ion-content>
</ion-menu>
<ion-nav id="nav" #content [root]="rootPage"></ion-nav>

  openPage(page) {
    this.menu.close();
    if(typeof page.component === 'function'){
      return page.component();
    }
    this.nav.setRoot(page.component);
  }

this.listPages = [
      {
        component: AccountPage,
        title: 'Account',
      },{
        component: ()=>this.events.publish('user:logout'),
        title: 'Logout',
      }
    ];

@anton_klochko Do you get the nav reference with: @ViewChild('content') nav: NavController;?

If not, you can give a try.

If you are using in the constructor, have in mind that you cannot get the NavController reference of a child nav this way. Use @ViewChild instead, like exposed above, or you will either get a null reference or another more external nav.

Hi, lucasbasquerotto. In my class MyApp I have @ViewChild(Nav) nav: Nav;

@anton_klochko Before calling the setRoot, try to call console.log(this.nav); to see if the function openPage() is being called and if nav is really undefined (you said that navCtrl is undefined, but that is not your variable name, unless you changed it).

In my case it worked with @ViewChild(Nav) nav: Nav;. Are you using Ionic2 RC2?

I am using Ionic2 RC2 and a brand new version, 0.0.42.

When I click on Account inside Menu … return is working … i do not use this.nav.setRoot(page.component);

This is my listPages.

Array[3]
0: Objectcomponent: function t(t){this.navCtrl=t}title: "Account"proto:
Object1: Objectcomponent: function t(t){this.navCtrl=t}title: "Settings"proto:
Object2: Objectcomponent: function (){return u.events.publish(“user:logout”)}title: "Logout"proto: Objectlength: 3

@anton_klochko So, if I understand correctly, you can choose the page in the menu, but inside the page you can’t use the NavController. If this is what is happening, try to add the NavController in the constructor of your page.

In your AccountPage you get the NavController like in the code below?

constructor(
	private navCtrl: NavController
) { }

Just to clarify, is your error (navCtrl undefined) happening when you click in the page in the menu, or in another moment?

If it happens when you click the page, change the openPage() method to:

  openPage(page) {
    this.menu.close();
    if(typeof page.component === 'function'){
      return page.component();
    }
    console.log('nav', this.nav);    
    this.nav.setRoot(page.component);
  }

And post what console.log() printed, so I can know better what is happening :slight_smile: .

If it is in another moment, I need to know where you are using the navCtrl instance and in which page (if is in your AccountPage, MyApp, or some other). If possible, post the code of the page where the error happens.

lucasbasquerotto, I can not choose the page in the menu. Nothing happend… navCtrl instance I use in MyApp.

This is nav. I can console.log(‘nav’, this.nav) only before if (typeof page.component === ‘function’), after my app not go.

e {_config: t, _elementRef: t, _renderer: t, parent: null, _app: t…}
_app: t
_cfr: e
_children: Array[0]
_config: t
_elementRef: t
_gestureCtrl: t
_hasInit: true
_ids: 0
_init: false
_keyboard: t
_linker: t
_queue: Array[0]
_renderer: t
_root: undefined
_sbEnabled: false
_sbGesture: e
_sbThreshold: 40
_sbTrns: null
_trnsCtrl: t
_trnsId: null
_trnsTm: 0
_viewport: t
_views: Array[1]
_zone: t
config: t
id: "n4"
parent: null
root: (...)
swipeBackEnabled: (...)
viewDidEnter: e
viewDidLeave: e
viewDidLoad: e
viewWillEnter: e
viewWillLeave: e
viewWillUnload: e
__proto__: n

navCtrl: undefined I can see in object page

Object {title: “Settings”, component: function, navCtrl: undefined}

@anton_klochko Then try to remove (or comment) your code:

if(typeof page.component === 'function'){
  return page.component();
}

Comment the 3 lines, because it seems that this.nav is not undefined, so setRoot should work. I think your code is entering the if.

Have in mind that when the typescript code is transpiled to javascript, classes become functions (the constructor itself).

If you do

if(typeof page.component === 'function'){
  console.log(page.component);
  return page.component();
}

you will see the constructor of your component logged.

I advise that you change your code, after all, ()=>this.events.publish('user:logout') is not a component, so you could put it outside your listPages array.

Or even better, create an array with click functions, like:

  this.menuItems = [
      {
        title: 'Account',
        fnClick: () => this.openPage(AccountPage)
      },{
        title: 'Logout',
        fnClick: () => this.events.publish('user:logout')
      }
  ];

  openPage(page) {
    this.nav.setRoot(page);
  }

And change your HTML to iterate over menuItems and have (click)="item.fnClick()" in your buttons.

Or change it in another ways, but keep in mind that some changes must be done in your code.

lucasbasquerotto, thanks a lot … with out

if(typeof page.component === 'function'){
  return page.component();
}

working … but this.nav.setRoot() dose not create on default back button yes ? Is it possible custom create back button ?

@anton_klochko To be able to go back you need to use push (so the new page will be added to the stack, on the other hand, setRoot replace the stack with the new page). So call this.nav.push(MyPage); instead of setRoot. If you don’t get the back button with push, you can place a custom one with (inside the ion-header):

<ion-navbar hideBackButton>
	<ion-buttons left>
		<button ion-button (click)="goBack()">
			<ion-icon name="arrow-back"></ion-icon>
		</button>
	</ion-buttons>

	<ion-title>My Page Title...</ion-title>
</ion-navbar>

And in your component:

constructor(private navCtrl: NavController) { }

goBack() {
	this.navCtrl.pop();
}

lucasbasquerotto, unfortunately goBack() run on white scrin … maybe better to use push ? Will it work with

this.menuItems = [
      {
        title: 'Account',
        fnClick: () => this.openPage(AccountPage)
      },{
        title: 'Logout',
        fnClick: () => this.events.publish('user:logout')
      }
  ];

?

@anton_klochko You can use that code with this.menuItems, but in the openPage() method you must use push so that you can go back (because push add the page to the stack, like I said in the previous post). If you use setRoot, the page will be the only one in the stack, so you cannot pop to the previous page in this case, because there will be no previous page.

TL;DR

Use push() and NOT setRoot() if you want to go back.

lucasbasquerotto, thank a lot, I understand.

lucasbasquerotto, good day! Оccasionally do not you know how to reach Zoom on image in Ionic 2 (pinch) ? Is it possible to reach by native methods ?

@anton_klochko Sorry, I haven’t used the zoom feature yet :confused: