Conditional rootPage

O have tried this on an Android device and it has not worked.

@richardshergold, @polska03, have you found any solution that worked for you ?

Hey guys,

just sharing what i’ve done. It is working with the beta-9.

in app.ts, my constructor looks like:

  rootPage: any;
  pages: Array<{title: string, component: any}>;

  constructor(
    private platform: Platform,
    private menu: MenuController,
    private authService: AuthService
  ) {
    this.authService.isUserLoggedIn().forEach(isUserLoggedIn => {
      console.log("is user logged in? " + isUserLoggedIn);
      this.rootPage = isUserLoggedIn ? HelloIonicPage : ListPage;
    });

    this.initializeApp();

AuthService is just a simple service that i’ve made myself. authService.isUserLoggedIn returns an Observable.

1 Like

Hey folks

I’m struggling with the same issue (FYI: I’m new to Ionic v2, so please be gentle ;-)). Within the constructor of the main component (using ionicBootstrap to initialize the app) I try to set the rootPage based on condition. The condition is met for sure, I verified by logs. Here’s the simplified code:

export class MyApp {
rootPage: any;

constructor(public platform: Platform) {
    let self = this;

    platform.ready().then(() => {
        if (true) {
            self.rootPage = LoginPage;
        } else {
            self.rootPage = HomePage;
        }
    });
}
}

ionicBootstrap(MyApp, null, {
mode: 'md'
});

Any idea where the problem is? Very much appreciated, thanks.

As a side note, in Typescript when you use the fat arrows (i.e. =>) you don’t need to do the whole let self = this; trick. Fat arrows will automagically do that for you. Which is to say, you can safely use this inside of fat arrow functions.

As for the question presented, this is just a guess but perhaps you can’t set the rootPage inside of platform ready callback? This is just a guess based off of my code, which doesn’t set it inside of the platform ready callback.

Thanks for the sidenote and your thoughts. It’s actually working when putting it outside of the platform ready callback. Unfortunately, I’ve the wait for a plugin which decides where to navigate to. Will keep you posted.

Very strange. It seems to work fine for me when I set the rootPage in the callback.

Does it work if you call setRoot on the Nav element?

You can do that by adding:

@ViewChild(Nav) nav: Nav;

then inside of the callback doing

this.nav.setRoot(MySuperAwesomePage);
3 Likes

Excellent, @SigmundFroyd, thanks! The solution with using ViewChild and setRoot is working fine. Although I had to use self = this, the reference of this was being changed within the callback.

I think the best way is to generate a third page which will redirect to one or other

1 Like

I want to change root page then i just tried this couple of lines. :
from page x to dashboard(side menu main page ):

this.navCtrl.setRoot(DashboardPage);
this.navCtrl.popToRoot;

Hi, I got multiple conditional rootPages, I tried both above, both got some issue.

export class MyApp {
rootPage: any = null;

constructor(public platform: Platform) {

    platform.ready().then(() => {
        switch (condition) {
          case xxx:
            this.rootPage = LoginPage;
            break;
          case yyy:
            this.rootPage = HomePage;
            break;
          // ....
    });
  }
}

In this way, I got blank first screen occasionally, app got resumed after several reboot. I inspected the page, there was no rootPage under ion-nav which told me rootPage was not successfully set, sometimes.

And I also tried using navCtrl.setRoot(whichPage), the blank first screen gone, the the bottom tool bar lost response for HomePage which used a toolbar in the bottom of screen, quite weird.

Any idea?

I’m on ionic 3.6 and cli 3.7, iOS 10

Is there any reason you wait for platform.ready()?
I have a similar case for my app (http://www.sleep-app.com) and it works without problems.

I show an IntroPage if it’s the first time the user opens the app -> if not i show the HomePage

// app.component.ts
constructor() {

const skipIntro = localStorage.getItem('skipIntro');
      if (skipIntro) {
        this.rootPage = HomePage;
      } else {
        this.rootPage = IntroPage;
        localStorage.setItem('skipIntro', 'true');
      }

// platform ready stuff 
// ...
}
1 Like

I don’t know how common this is in the wild, but localStorage is not guaranteed to be persistent. The OS can wipe it to recover storage space at any time. Ionic Storage might be a more reliable choice.

Hmm. you might be right…
I always thought its only an iOS 8 thing that it might get cleared…
Since Ionic Storage is Promise based my approach from above does not work either i guess…

In an other app i had a loadingPage i showed every time when the app started and there i decided after (a minimum timespan) where to go next depending on the data.
it worked quite well for my usecase back then…

besides that - why isn’t it common to show an Intro/Tutorial/Onboarding - Page on first app start :smiley:

What I meant is that if you store that state in localStorage, you might end up showing that intro again at random instances where localStorage got wiped out from under you.

Since your situation is a one-way street, Promises should be fine. For the related case of “is user authenticated?”, I think it works much better to handle this using rxjs, as described here.

I had to wait for platform.ready since I need to call some cordova plugin for boot logic. In your case, you set conditional rootPage in constructor, it looked well

Ah sry, my fault - i was misreading the “quoted area”.
@myfifth: then i would probably show a loading page by default and handle the async stuff there.
I also experienced some problems when the rootpage is not set in the constructor or ngOnInit lifecycle hook.

Did anyone find a solution for this? I continuously get a blank screen trying to set the rootPage conditionally like the code samples in this thread.

It worked for me, i am in ionic 3. Thanks

There is really no difference, since you are using the ‘fat arrow’ function…