ionViewCanEnter together with Native Storage

I have a screen where your mobile number must exist in local storage first before you are allowed to enter that screen.

So I have a simple ionViewCanEnter() function that should just return true or false obviously, but I need to do the Native Storage check inside it first, and the result of the storage, should return outside of scope to the ionViewCanEnter, almost like a promise. At the moment the ionViewCanEnter(): boolean does not wait for the storage.

How can I let the true or false of the storage, be returned as the boolean for ionViewCanEnter?
Setting a public variable does not work, here is my code:

export class Qrscan {

  loading: any;
  localStorage: boolean = false;

  constructor(public navCtrl: NavController, public navParams: NavParams, private nativeStorage: NativeStorage, 
    public nandos : NandosProvider, public loadingCtrl: LoadingController) {

  }

  ionViewCanEnter(): boolean {

      // Check the native storage for a mobile number to see if you can enter and return a boolean

      this.nativeStorage.getItem('mobile').then(data => {
        console.log('Mobile found in storage, stay', data.mobile);
        this.localStorage = true;
      }, error => {
        console.log('Mobile NOT found, please leave', error);
        this.localStorage = false;
      })

      return (this.localStorage ? true : false);

  }

}

I would think about this the other way around: instead of guarding against entering the page, simply disable or do not present whatever navigation element leads to it until the proper conditions exist.

I also thought about that, but what if this page doesn’t have an element that clicks to it? This is the Root page coming in from component.ts. I have a “then” in there that catches the result of the guard:

this.nav.setRoot(page).then(
      canenter => {

        console.log('Can Enter: '+canenter);
        if (!canenter) {
          this.nav.setRoot(alternativePage);
        }

      })

I would do conditional assignment to rootPage in the app component (and I would use ionic-storage instead of NativeStorage):

this.storage.get('mobile').then((mobile) => {
  if (mobile) {
    this.rootPage = DashboardPage;
  } else {
    this.rootPage = AlternativePage;
  }
});

In reality, I would use an Observable here from a service provider instead of directly interacting with storage on a one-shot basis, because it scales more naturally to handling login/logout.

Awesome! Thank you that worked better. I will rather use the ionViewCanEnter() when navigating via elements onscreen.
Yes I think a service is a good idea, thanks!

Obviously you’re free to completely ignore my opinion, but I have yet to come across a use case where ionViewCanEnter makes any sense. I think it’s a solution in search of a problem that entices people into bad designs.

How do you know what the AlternativePage is? Im confused on how to find out which page was trying to be accessed in order to set the AlternativePage.

I like the idea of implementing the storage check/auth controller at the beginning.

Something like this is not working for me…of course im a newb

@Component({
  templateUrl: 'app.html'
})
export class MyApp {

  rootPage:any = 'WelcomePage';

  constructor(public authService: AuthServiceProvider,private storage: Storage,platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {

    if( !this.authService.apikey_check()){   //<---- I think this just returns undefined when it should return a bool
      this.rootPage = 'LoginPage';  
    }
    
    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.



      statusBar.styleDefault();
      splashScreen.hide();
    });
  }
}

then in the service provider is this:

 apikey_check(){
  this.storage.get('apikey').then((val) => {
    if(val){
      return true;
    }
    else{
      return false;
    }
    });
  }

See this post. Your service provider function is of type three, so the first word of it should be return. It should also have a proper return type declaration and a name that follows typical JavaScript naming convention of camelCase.