*ngIf does not recognize changes in Ionic 4.8.1

Hi

I have migrated from @ionic/angular 4.4.0 to @ionic/angular 4.8.1
After the update my pages cant discover screen rotate with *ngIf

The above statements works fine with 4.4.0 and the screen rotate is discovered.
In the new version 4.8.1 this only works the first time the page loads, but never when the screen rotates.

Thanks in Advance!

Share the code! It works for me.

The following HTML code will work with Ionic 4.4.0 but the ngIf will not discover screen rotation with the new version 4.8.1

  <ng-container
    *ngIf="platform.isLandscape(); then showLandscape; else showPortrait">
  </ng-container>
  
  <ng-template #showLandscape>
    <p>
        showLandscape
    </p>
  </ng-template>
  
  <ng-template #showPortrait>
    <p>
        showPortrait
    </p>
  </ng-template>

Your code works for me.

i’m using Ionic V5.2.4

I cant get this to work with the latest Ionic version.
I have created a new project with the latest ionic:

ionic start TestNgIf sidemenu --cordova --type=angular

Ionic Info Gives:
Ionic:

Ionic CLI : 5.2.7 (/usr/local/lib/node_modules/ionic)
Ionic Framework : @ionic/angular 4.8.1
@angular-devkit/build-angular : 0.801.3
@angular-devkit/schematics : 8.1.3
@angular/cli : 8.1.3
@ionic/angular-toolkit : 2.0.0

Cordova:

Cordova CLI : 9.0.0 (cordova-lib@9.0.1)
Cordova Platforms : ios 5.0.1
Cordova Plugins : cordova-plugin-ionic-keyboard 2.1.3, cordova-plugin-ionic-webview 4.1.1, (and 4 other plugins)

Utility:

cordova-res : 0.6.0
native-run : 0.2.8

System:

ios-deploy : 1.9.4
ios-sim : 8.0.2
NodeJS : v12.9.1 (/usr/local/Cellar/node/12.9.1/bin/node)
npm : 6.10.3
OS : macOS Mojave

I have added platform to the homepage implementation and added the following html kode:

<ng-container
    *ngIf="platform.isLandscape(); then showLandscape; else showPortrait">
  </ng-container>
  
  <ng-template #showLandscape>
    <p>
        showLandscape
    </p>
  </ng-template>
  
  <ng-template #showPortrait>
    <p>
        showPortrait
    </p>
  </ng-template>

On the initial load the page works fine, but when i rotate the screen *ngIf does not recognize any changes.

I suspect your problem is tied up with change detection. Instead of platform.isLandscape(), I would combine the ScreenOrientation plugin’s onChange emitter with the AsyncPipe.

I have tried the ScreenOrientation plugin and updated a variable on the page that i test against in the HTML , but *ngIf wont update the page when the value is changed.

I can write to the colsole log when the rotate happens and I can see that my variable has been updated, but *ngIf wont recognize the change .

This was not any problem with the 4.4 version of the @ionic/angular framework.

If change detection does not seem to work in a template but somehow does work in the code then my experience is that there something else wrong with the template giving the angular engine a hard time

Have u tried the mechanism in a new simple app to see if the mechanism works?

Wrapping in a zone may be something for some plugins

I think this is a new bug in Ionic/Angular

I have added some source code to illustrate the problem bellow. When updating the variable isLandscape nothing happens, but after adding a dummy method that just prints the variable isLandscape to the console log, then the change in isLandscape is discovered in HTML

In earlier versions of ionic this would work fine.

home.page.html

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
    <ion-title>
      Home
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

  <ng-container
    *ngIf="isLandscape; then showLandscape; else showPortrait">
  </ng-container>
  
  <ng-template #showLandscape>
    <p>
        showLandscape
    </p>
  </ng-template>
  
  <ng-template #showPortrait>
    <p>
        showPortrait
    </p>
  </ng-template>
  <h1>isLandscape = {{isLandscape}}</h1>
</ion-content>

home.page.ts

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

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  public isLandscape: boolean = false;
  private handlerOrientationChange:any;
  
  constructor(
    public platform: Platform  
  ) {
    console.log("HomePage constructor");


    this.handlerOrientationChange = () => {       
      //This change is not discovered by Ionic/Angular
      this.isLandscape = this.platform.isLandscape();
    };
    window.addEventListener("orientationchange", this.handlerOrientationChange);
    
    //when this method run then Ionic/Angular is able to discover changes in the variable isLandscape
    this.dummy_logIsLandScapeVariable(); 
  }
 

  dummy_logIsLandScapeVariable() {
    setTimeout(() => {      
      //After writing this.isLandscape to log then the html is updated!
      console.log("** ** ** this.isLandscape = " + this.isLandscape );  
      this.dummy_logIsLandScapeVariable();
    }, 2000);
  } 


  ngOnInit() {
  }

  ngOnDestroy() {
    console.log('HomePage destroyed!');
    window.removeEventListener("orientationchange", this.handlerOrientationChange);    
  }
}

I have solved the problem with NgZone for now.
When I wrap the update of the variable that holds information about the screen orientation inside ngzone then *ngIf is able to discover changes.

home.page.ts

import { Component, NgZone } from '@angular/core';
import { Platform } from '@ionic/angular';


@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  //-- handle orientation
  public isLandscape: boolean = false;
  private handlerOrientationChange:any; 
  //-- end 
  constructor(
    public platform: Platform,
    private zone:NgZone  
  ) {
    console.log("HomePage constructor");

    //-- handle orientation
    this.isLandscape = this.platform.isLandscape();
    this.handlerOrientationChange = () => {       
      this.zone.run(() => { 
        this.isLandscape = this.platform.isLandscape();
      });
    };
    window.addEventListener("orientationchange", this.handlerOrientationChange);
    //-- end
  }
 
  ngOnInit() {
  }

  ngOnDestroy() {
    //-- handle orientation, stop listening.
    window.removeEventListener("orientationchange", this.handlerOrientationChange);    
  }
}