Ionic version: (check one with "x")
[ ] 1.x
[x] 2.x
I'm submitting a ... (check one with "x")
[x] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://forum.ionicframework.com/ or http://ionicworldwide.herokuapp.com/
Current behavior:
When using NavController.setRoot() to switch to a page that has a menu on the same side as the current page, the new menu will disable itself.
The reason for that seem to be that the NavController starts a transition for both pages, which causes the new page to attach to the DOM while the old page is still active. This causes the new menu to disable itself because menu.ts checks explicitly for other active menus on the same side in ngOnInit().
Expected behavior:
Either the old menu should be disabled already when the transition is started or the new menu should re-enable itself after the transition has been completed.
Steps to reproduce:
The problem seems to occur every time setRoot() is called on a NavController with a page that has a menu while the NavController already has an active menu (on the same side).
I created a Plunker here to show the behavior.
The first page has a menu and works fine, clicking the button to switch to the second page also works fine. The next button switches back to the MenuPage and triggers the problem, the menu will not open anymore.
When you do the same steps again, the menu will work again (because there is no active menu at this time), third time will fail again and so on.
Other information:
The behavior is the same at least for Ionic 2.0.1 and 2.3.0 (Plunker is for 2.3.0).
Hello, thanks for opening an issue with us, we will look into this.
@BStbck why are you doing this so complicated?
@manucorporat The example was made to demonstrate the behavior that surprised us in a larger, more complex application. Do you mean using setRoot() in this way is generally not supported?
Btw sorry I didn't want to be rude. I closed it accidentally haha
Well, here's the thing, ion-menu does not play really well, when it is not at the root. But I will look at improving the support of ion-menu inside the navigation stack.
Don't worry about it :)
I'm not sure I understand it yet, though. The menu is at the root (the navigation controller inside AppComponent). The problem is just that setting it to another instance of the same (menu) page doesn't really work.
Would you suggest just having one menu (at root) for the lifetime of the app?
i dont know if its the same problem, but i made a popover with a logout button. on click of the logoutbutton i navigate to my loginpage with - this.nav.setRoot(LoginComponent) - where i dont have a sidemenu.. after login again, the buttons to open the left and right sidenav are not working any more.
Yeah. happens with me too. After setRoot() on any of the child components on a menu (components inside the content on the menu), menu just does not work anymore.
Any news about this issue? I'm enabling the menu when the user enters the view, it works fine when the view is entered without setting it to root, but it does not open even with this.menuCtrl.isEnabled()
returning true.
ionViewWillEnter() {
this.menuCtrl.enable(true)
}
Exact same problem. Side menu is disabled and then on popup they login - using setRoot to take them to their homepage view and sidemenu does not enable ... user has to refresh
specifically setRoot from a modal is the issue. I got around this by doing this from a view that was loaded using nav.push
Same problem here, but i did diferent, I set ion-menu inside each page that i want have diferents menu.
when i go from one page with menu to other with menu the menu on the other page dont work and not appears the menu button on the header.
Hey, I solved my problem.
In app.html i created two menu and given a ID for each one.
In pages.ts i declared the menuController and call the method enable with true and as second parameter the id of menu that i want show.
In other pages where don't need show menu set the menu.enable(false)
I solved with event.
in app.component.ts
events.subscribe('user:changed', (user, time) => {
this.nav.setRoot(HomePage);
});
when dismiss the modal
```
this.events.publish('user:changed', user, Date.now());
this not working after using setRoot() method come guys any ideas?
same issue here, using a popover to logout and set login page as root after logging in the main page is set as root, menu button shows. When displaying menu.isOpen() I see the button toggling true/false, but menu is not showing
This is not only a v2 issue. I experience this in v3.12.0
Edit: Solved this by using onDidDismiss of modal to change root
I've tried all of the above solutions i.e. event propagation, page push but no luck. the hamburger icon is present but nothing happens when I click it. When I open/close the app, it works
I am on the latest ionic version 3.7.1.
I am setting HomePage
to root that is a tab layout page usingionic2-supertabs
menu markup is defined in app.html (menu content is defined in a component btw)
<ion-menu persistent="true" [content]="content" id="hamburger-menu">
<hamburger-menu></hamburger-menu>
</ion-menu>
and in app.component.ts I've enabled the menu (it's already enabled throughout the app i'm trying to force enable it again)
ionViewDidEnter() {
this.menuCtrl.enable(true, "hamburger-menu");
}
I'm on the last page e.g. final-sign-up.ts that triggers a modal for user info, after which the root page is set when the modal is dismissed
let modal = this.modalCtrl.create('WelcomeModalPage');
modal.onDidDismiss(data => {
this.navCtrl.setRoot(HomePage);
this.navCtrl.popToRoot();
});
modal.present();
I'm currently seeing this issue in V3 as well. I've tried @akhatri's work around but unfortunately the menus are not enabled after dismissing a modal. I can see the menu icon but clicking it does not open the menu and I can't seem to explicitly enable the menu.
I too am having this issue and need to find an answer by this Friday for an internal review D:
app.component:
<ion-menu [content]="content" id="menuRight" side="right">...</ion-menu>
Here's one of my menus.
Login screen:
tryLogIn(){
this.navCtrl.setRoot(WelcomeTreatmentPage);
}
This works fine, sending me to welcome and allowing the menus to open.
Legal modal:
accept(){
this.viewCtrl.dismiss();
this.navCtrl.setRoot(WelcomeTreatmentPage);
}
This does not work; it forwards me to welcome but menus no longer function.
I tried this but it gives the error "Uncaught (in promise) removeView was not found."
this.navCtrl.setRoot(WelcomeTreatmentPage);
this.viewCtrl.dismiss();
So I tried these too but they do not work either:
this.viewCtrl.dismiss();
this.viewCtrl.onDidDismiss(() =>{
this.navCtrl.setRoot(WelcomeTreatmentPage);
});
this.viewCtrl.dismiss();
setTimeout(() =>{
this.navCtrl.setRoot(WelcomeTreatmentPage);
}, 2000);
md5-4580f6720d64f931eabb14e9374e34ae
this.viewCtrl.dismiss().then({
this.navCtrl.setRoot(WelcomeTreatmentPage);
});
Hey i had the same problem then i worked around it . This issue appears in using setroot() 2 times so i created events that fires the setroot method try it .
If both of your pages contain menus, you should just disable the current menu before setting the new root.
this.menu.enable(false);
this.navCtrl.setRoot(yourRoot);
Hope this helps you ;)
My menu is always on the main app component. I might try what you have suggested and get back to you, but I want to point out that I don't have a new root - it's always the same root being activated from different pages if that makes sense?
If you always keep the same root consider using :
navCtrl.popToRoot() to go back to your root component, and while navigating use navCtrl.push(newPage), which will also create a more mobile friendly interface with the transitions between the pages and so on.
up. Still an issue. Having trouble with that too... menu button does not function when setting root. Anyone has an answer ? Or a functional work around ? :weary:
I have made sure that it is not a bug. If this happens to you, you are probably using an overlay component like modal or popover somewhere in the app and that overlay component navigates the user to another page. This creates a new navigation stack. You need to make sure that you use the root nav stack even when you navigate from the overlay component.
If both of your pages contain menus, you should just disable the current menu before setting the new root.
this.menu.enable(false);
this.navCtrl.setRoot(yourRoot);
I had a similar issue and navigating between two pages with a menu each and disabling the menu before pushing works! Now the menu appears correctly, but it does not load its root page and instead the latest page from the other menu is still displayed.
Currently I assign the rootPage in the menu page constructor. Playing around and moving it to other placed (like ionViewDidLoad, ngOnInit etc.) often leads to strange URLs (with the same output, though) like: http://localhost:8100/#/menu-b/nav/n6/menu-a-subpage/nav/n7/menu-a-subpage
when navigating from page menu-a-subpage
(page in menu-a
) to menu-b
.
However, I expect the URL to be like #/menu-b/menu-b-root-subpage
.
Any ideas?
This helped me: this.viewCtrl.dismiss().then(() => this.app.getRootNav().setRoot('SomeLazyPage'));
I tried it and it throws a runtime error: Uncaught (in promise): navigation stack needs at least one root page.
Same issue here and nothing works for me
I was with the same issue but @samarthagarwal is right, i was calling push from another stack... just pushed outside the modal with an event, solved the problem for me, thanks!
My problem seems to be solved by a little work around. Putting a dummy page in the root and dismissing the menu's view before pushing the other menu to the navigation stack works.
It's almost the code suggested by @petvoj but I use push()
instead of setRoot()
to keep the dummy page at root (so switching back to the other menu still works):
this.viewCtrl.dismiss().then(() => this.app.getRootNav().push('SomeLazyPage'));
It opens the correct subpage and shows the correct url. Without a dummy page (and the menu being root) the dismissing fails, because the stack would be empty for a short time, I guess.
However, during navigation, the dummy page is visible in the browser for short moment, which isn't a big problem for me.
Hey guys, this is my workaround. I went ahead and modified OP's plunker sample. I added (swiperight)="checkMenu()"
to ion-nav
. Literally enabling the menu right when its toggled. This seems to be working decently for me. Also you can modify your menu toggle button if you have that instead, just do (click)="checkMenu()"
and add that checkMenu
function to your ts file. Im sure there are better solutions. Hope this helps someone.
<ion-menu id="menu" [content]="content" class="main-menu">
<ion-content class="main-drawer-content">
<ion-title>
Menu
</ion-title>
</ion-content>
</ion-menu>
<ion-nav [root]="rootPage" #content (swiperight)="checkMenu()">
</ion-nav>
import {Injectable, Inject, Component, Input, AfterViewInit, OnDestroy, ViewChild} from '@angular/core';
import {MenuController, App, Nav, Menu} from 'ionic-angular';
import {AppComponent} from '../../app/app.component';
import {HomePage} from '../home/home';
@Component({
selector: 'menu-page',
templateUrl: 'pages/menu/menu.html'
})
@Injectable()
export class MenuPage implements AfterViewInit, OnDestroy {
HomePage = HomePage;
rootPage: any;
constructor(public menuCtrl:MenuController) {
this.rootPage = HomePage;
}
ngAfterViewInit() {
}
ngOnDestroy() {
}
checkMenu() {
this.menuCtrl.enable(true);
this.menuCtrl.toggle();
}
}
Same issue here. Anyone found the solution yet?
@samarthagarwal solution worked for me. There is different way to push a page from overlay component. Here is the link: https://ionicframework.com/docs/api/navigation/NavController/#navigating-from-an-overlay-component.
So it was not a bug.
The comments from @syedsaadmahmood and @samarthagarwal helped me put it together. They are right. If you use push() or setRoot() from a popover or a modal overlay component then you have to make sure you do it on an instance of the root navigation controller.
The documentation says to use
this.appCtrl.getRootNav().push(SecondPage);
The new problem is that getRootNav() is deprecated and won't be available in the next major release. Where do we go from here?
you can do something like this:
import { App } from 'ionic-angular';
(...)
this.app.getRootNavs()[0].push('SomePage');
but I don't know if this is the best way to solve it ;)
That’s perfect. Somebody else proposed a little bit more to avoid risking a
null pointer exception:
getNav() { var navs = this._app.getRootNavs(); if (navs && navs.length > 0)
{ return navs[0]; } return this._app.getActiveNav('nav'); }
I found it here:
There are a lot of opinions about what to be done, but I guess we will just
wait on the word from the Ionic team.
On Wed, Jan 31, 2018 at 6:59 AM Simon notifications@github.com wrote:
you can do something like this:
import { App } from 'ionic-angular';
(...)
`this.app.getRootNavs()[0].push(SomePage);—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/ionic-team/ionic/issues/10989#issuecomment-361957620,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AUJ84rOEbzRKSCxgTT0X3Mv4ATLGfu0Oks5tQH_ggaJpZM4Mu48K
.
Okay, so the issue for me was simply to include the HTML that generates the menu button when I made the new page.
For example, when you generate a page with ionic g page name it will generate content that looks a little like this in pages/name/name:
<ion-header>
<ion-navbar>
<ion-title>name</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
</ion-content>
However when you compare that to the original "home" page HTML you can see a subtle difference in ion-navbar:
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Home</ion-title>
</ion-navbar>
</ion-header>
As you can see, the hamburger icon is put there via manual HTML and not generated in the navbar by ionic. You can implement this as follows:
app.component.ts
openPage(){
this.nav.setRoot(SubPage, {});
}
app.html
<ion-menu [content]="content" persistent="true" id="main-menu">
...
<ion-list>
...
<button ion-item (click)="openPage();"><ion-icon name="cart"></ion-icon> Sub Page</button>
...
</ion-list>
...
That should be all. By manually adding the hamburger toggle to the navbar and using persistent="true" on the ion-menu all is solved and you can still toggle the menu.
Hi guys,
Instead of calling the setRoot method, I solved this issue by using directly the rootPage property :
menu.ts
export class MenuPage {
...
rootPage : any = HomePage;
...
openNavPage(item) {
switch (item.title) {
case "Login": this.rootPage = LoginPage;
break;
case "Home": this.rootPage = HomePage;
default:
break;
}
...
}
menu.html
<ion-menu [content]="content">
<ion-header>
<ion-toolbar>
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<button ion-item *ngFor="let item of items" (click)="openNavPage(item)" icon-start>
<ion-icon [name]="item.icon" [ngStyle]="{'color': item.color}" item-start></ion-icon>
{{ item.title }}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav id="nav" #content [root]="rootPage"></ion-nav>
but I don't know if it's the best solution, just started learning ionic :)
I finally figured out a temporary fix.
First, the cause:
When you navigate to a page, the page html content is supposed to be added within <ng-component class="app-root"></ng-component>
element, but instead it's added outside it. That gives it a higher z-index over the menu and it's overlay. So, when you toggle the menu, it's actually activated but you just can't see it.
Now the workaround
Add the following to your app.scss
file or anywhere that it can be effective globally:
ng-component{
&.app-root{
z-index: 10000;
}
}
The value 10,000 of the z-index is so that it will be above the pages that are added outside the ng-component but still below the modals and popovers which are above 10,000.
I am using Ionic 3 conference template. From tab 1, I am opening nested modal like tab1>modal1->modal2->modal 3. Now from modal 3, I have to go back to tab1. I tried using this.navCtrl.setRoot. I going back to tab1 but the menu on the navbar of tab1 no longer working...please suggest how I can fix it
@yogeshbansal As you are in modal, use "this.appCtrl.getRootNav().setRoot(Page);"
As it is mentioned in Ionic official documentation.
try before setroot this
goAplicarFiltro(){
this.menuCtrl.enable(false,"menu2");
this.menuCtrl.enable(false,"menu1")
this.navCtrl.setRoot(MercadoPage, { param1:this.valor_atual_compra, param2:this.carrinho, param3: this.idLinha, param4: this.idSubgrupo, param5: this.idSessao });
}
Hi guys,
please fix. I'm using 4.0.3
page is added outside <ng-component class="app-root"></ng-component>
. In my case, this issue occurred when calling two navCtrl.push() then in the third page, i called navCtrl,setRoot.
the workaround suggested by @topeysoft didn't work because it will just display a different page (the page within
The comments from @syedsaadmahmood and @samarthagarwal helped me put it together. They are right. If you use push() or setRoot() from a popover or a modal overlay component then you have to make sure you do it on an instance of the root navigation controller.
The documentation says to use
this.appCtrl.getRootNav().push(SecondPage);
The new problem is that getRootNav() is deprecated and won't be available in the next major release. Where do we go from here?
it's working! thanks!
@deliaelvina you can do sth like:
this.appCtrl.getRootNavs()[0].push(SecondPage);
which might not be best but at least not deprecated ;)
This issue has been automatically identified as an Ionic 3 issue. We recently moved Ionic 3 to its own repository. I am moving this issue to the repository for Ionic 3. Please track this issue over there.
If I've made a mistake, and if this issue is still relevant to Ionic 4, please let the Ionic Framework team know!
Thank you for using Ionic!
Issue moved to: https://github.com/ionic-team/ionic-v3/issues/201
Most helpful comment
I'm currently seeing this issue in V3 as well. I've tried @akhatri's work around but unfortunately the menus are not enabled after dismissing a modal. I can see the menu icon but clicking it does not open the menu and I can't seem to explicitly enable the menu.