ionViewCanEnter isn't behaving as expected

According to ionic’s blog piece on Lifecycle hooks, the ionViewCanEnter:

ionViewCanEnter: Fired before entering into a view, allows you to control whether the view can be accessed or not (returning true or false).

According to the docs, ionViewCanEnter:

Runs before the view can enter.

Point is, before a page is entered and displayed, the ionViewCanEnter should be resolved to true or false.

In my case, that ain’t happening. There’s a Flash Of Unwanted Content (FOUC)

The behavior I experience is, the page Loads before the ionViewCanEnter happens. See what I mean in this 15 seconds video. I reload the page several times. When you see the lag, it is hard to unsee again:

My setup:

cli packages: (/some/where/node_modules)
    @ionic/cli-utils  : 1.9.2
    ionic (Ionic CLI) : 3.9.2
global packages:
    Cordova CLI : 7.0.1 
local packages:
    @ionic/app-scripts : 2.1.3
    Cordova Platforms  : android 6.2.3 ios 4.4.0
    Ionic Framework    : ionic-angular 3.6.0
System:
    Android SDK Tools : 26.0.2
    Node              : v7.10.1
    npm               : 4.2.0 
    OS                : Linux 4.10

My code

This is the function in my Authentication service.

  isLoggedIn() {
    let token = localStorage.getItem('token');
    if (token) {
      return true;
    }
    return false;
  }

Then I’m using the above in my ionViewCanEnter hook in my component as so:

  ionViewCanEnter() {
    if(!this.auth.isLoggedIn()) {
      this.navCtrl.setRoot(WelcomePage);
    }
  }

My rootpage in my app component is the HomePage (localhost:8100/#/home). When user isn’t logged in, they should not see that page.

Yet, in the video above, they see that page, because ionViewCanEnter isn’t running on time.

This looks a lot more like a bug to me. Because I think nothing should come up UNTIL the hook resolves FIRST. In this case, the page resolved, before the hook kicked in, causing the FOUC.

PS: Before you jump to saying the front-end auth checks is baseless and auth checks should be done server-side, guess what. All my server-side checks are in place. The front-end tweaks for aesthestics sake. You don’t want user to enter long piece of text, only to tell the user after posting: “You’re not logged in”.

See this: ionViewCanEnter still executing page load

In my case, returning a boolean or not, protected page still flashes.

I’ve tried this too, with uncommented return false. Still flashes.

  ionViewCanEnter() {
    if(!this.auth.isLoggedIn()) {
      this.navCtrl.setRoot(WelcomePage);
      return true;
    }
   // return false;
  }

What are you doing in your page constructor?

This is my constructor:

  constructor(public navCtrl: NavController,
    public auth: AuthenticationProvider,
    public overlay: Overlays) {

  }

Nothing in it!

Well ok. First, I should say that I don’t use ionic guards because I think they’re useless. However, you’re running into the difference between a view and a page. The page is rendered independently of the view. You’re only controlling access to the view with your guard. If you want the page not to render without auth, you need to control that separately. That’s what I do, and I ignore guards completely. Maybe I’ll put them in later for extra cosmetics, I don’t know. But my advice is to organize your navController so you’re only pushing pages the user has access to. The guard is there for if the user goes to a bookmark when not logged in or something.

Which is what I do. However, I’m using it for a pwa, so entering #/home in the browser, if the user is logged in, fine!

But if the user isn’t logged in, that’s where I don’t want whatever, page/view/whatever to show.

In this case, then it means I need something like ionPageCanEnter, which doesn’t exist.

The fact that guarding pages is a frustrating experience to implement unlike the canActivate feature in Angular, building PWA with Ionic is still not primetime, and not worth to use for a production app, because I can’t ship a website that flickers here and there when users access via deeplinks.

Can Ionic stop pushing the PWA preaching if the framework isn’t ready for primetime, because I’m beginning to regret going with Ionic?

Tell the devs that if you want. I’ve been posting on this forum for months that Ionic is good for handheld devices, and won’t be a tool for PWAs until at least Ionic 4. If your primary goal is to build a PWA, Ionic 3 is the wrong tool.

2 Likes

I’ve come to learn that the hard way. I’ll be dropping all ionic for now then.

such a waste of time.

Ionic 4 likely won’t ship a PWA support fully: https://github.com/ionic-team/ionic/milestone/56

Yes, that approach doesn’t work well.
if it’s only for the logged in try using a dynamic rootPage in the main component ( App )
rootPage: any = "HomePage"
then in the constructor
if ( auth.isLoggedIn() ) {
this.rootPage = “TabsPage”
}