Set root without tabs


#1

I have the normal workflow of an app with login: First page is the login screen and you get to the tabs page after login. Now I’m trying to implement a logout button. But if I use

this.navCtrl.setRoot(Login);

the tabbar is still displayed.
I also tried to use

@ViewChild(‘myNav’) nav: NavController
[…]
this.nav.setRoot(Login);

which turns out to be undefined.

Any advice how to make a logout with goes back to Login without the tabbar?

I created a minimum example if someone wants to try it himself. I’m happy to send the src folder if needed :slight_smile:


#2

Exactly de same case here, with the same use case.

The tab bar still showing after:

this.nav.setRoot(Login);


#3

I report a bug about that yesterday and it turns out it is not :wink:

To set a full new root outside the tabs, do something like:

 this.app.getRootNav().setRoot(Login);

@manucorporat explained this:

You are changing the root of the tab, remember that each tab has his own navigation stack. You have to setRoot() to the root navigation controller:


#4

I think you are going about this backwards. It feels much more natural to me to do this reactively instead of declaratively, by having an observable in a service somewhere that tracks the authentication state of the user. To log out, inject that service and call its logout function. In the application component or some root page, also inject the same service, subscribe to it, and change root pages there.


#5

Amazing! Thank you! @reedrichards

BTW, I did with subscribe

At some page:

   logout() {
        this.events.publish('user:logout');
   }

In a centralized place:

   this.events.subscribe('user:logout', () => {
        this.app.getRootNav().setRoot(LoginPage);
    });

Tabs do not disappear when using setRoot
#6

Thx for the centralized code example, looks coolio!


#7

Using an Observable makes this a bit easier:

@Component({ template: "<ion-nav [root]='rootPage'></ion-nav>" }) export class MyApp { public rootPage: any; constructor( public platform: Platform, public sessionSvc: SessionService ) { platform.ready().then(() => { // observe login state and route accordingly this.sessionSvc.isLoggedIn.subscribe(isLoggedIn => { if ( isLoggedIn ) { this.rootPage = TabsPage; } else { this.rootPage = LoginPage; } // end if }); }); } }
then some logout method:

public logout(): void { this.isLoggedIn.next(false); }


#8

How did you manage to get an instance of app (this.app) ?

Tnx.


#9
constructor(private app:App) {}

#10

Tnx @reedrichards.

Do I need to import anything? If I just add this parameter to constructor I get an error:

Can't find name App


#11

import { App } from ‘ionic-angular’;


#12

Thanks Guys! It works great now!


#13

Yes, this solution works; but it breaks the path to images on all views when running on devices or emulators.


#14

I really like the kind of approach you are suggesting @rapropos, about having some service handling changes in the root page, but I’m pretty new to the Ionic framework and really don’t have much clue about doing what you proppose in your answer.

Could you give me some advice or point me to some documentation where this is explained in more detail?