ionViewCanEnter Not Working As Expected In Components


#1

Interesting issue I’ve run into: when including a component or page in another page it seems that ionViewCanEnter isn’t firing. If you access a page directly, it’ll fire, but including it in another page using its selector causes it not to fire. I tried making a component and including that in a page and it’s not working. I need a special view on two pages and, trying to reuse code, decided to move my code to a component and include that in both pages, but the issue is that the HTML template calls a function and that function requires some async data before it can respond so I need to have the view held back until I receive that data. Any ideas on how to solve this?

Here’s my component:

import { Component } from '@angular/core';

/**
 * Generated class for the PageStylesComponent component.
 *
 * See https://angular.io/api/core/Component for more info on Angular
 * Components.
 */
@Component({
  selector: 'page-styles',
  templateUrl: 'page-styles.html'
})
export class PageStylesComponent {

  text: string;

  constructor() {
    console.log('Hello PageStylesComponent Component');
    this.text = 'Hello World';
  }

  ionViewCanEnter(): boolean | Promise<any> {
    return this.auth();
  }

  auth() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(true);
      }, 2000);
    });
  }

}

HTML for component:

{{text}}

I have this imported to another page as so:

    <ion-col col-4>
      <page-styles></page-styles>   
    </ion-col>

When running this other page, I get Hello World printed immediately. Further, console does not show that the ionViewCanEnter is fired. I get:

Hello PageStylesComponent Component
ionViewDidLoad EditStylesPage (The other page)

But no ionViewCanEnter from my component. I’ve been doing tons of research and can’t find a solution.

CLI Info:

cli packages: (/usr/local/lib/node_modules)

@ionic/cli-utils  : 1.19.2
ionic (Ionic CLI) : 3.20.0

global packages:

cordova (Cordova CLI) : 8.0.0 

local packages:

@ionic/app-scripts : 3.1.2
Cordova Platforms  : android 7.0.0 ios 4.5.4
Ionic Framework    : ionic-angular 3.9.2

System:

Android SDK Tools : 26.1.1
ios-deploy        : 1.9.2 
Node              : v8.10.0
npm               : 5.6.0 
OS                : macOS High Sierra
Xcode             : Xcode 9.4.1 Build version 9F2000 

Misc:

backend : pro

Thanks for your help!


#2

I would concentrate on removing this requirement. Initialize all the relevant component controller properties to dummy values, and then update them whenever the asynchronous operation completes, allowing Angular change detection to do its job. You want as few function calls in templates as possible, and zero heavy ones like you are describing.


#3

Hello @rapropos,
is this not a event fired from page? Sorry for that beginner question, because I use in custom components ngWhatvever.

@iescentral Imho from the user view it is maybe not clear why he can not leave the page. Maybe he thinks, that here is something broken. I personnel would prefer a kind of message on that page, that phone is calcultaing, retrieving, connecting, whatever.

Best regards, anna-liebt.


#4

Ionic lifecycle events are only triggered on pages.

That’s a good strategy. However, it’s still contraindicated here if the goal is to “hold up” things. Asynchronous things are supposed to be asynchronous, and attempting to hammer them into synchronous operation is a bad idea.


#5

Hello @rapropos,

thanks for the link and clarification.

Best regards, anna-liebt


#6

Thank you. I ended up calling the exact same function from typescript and modifying my array before setting it.