Problem with ionic + cordova browser build + ngIf + browser-back


#1

Greetings Ionic-People,

we have a little problem using the cordova-browser build of ionic 3.

Long story short: If you come back to an already visited Ionic page using the browser back button and interact with that page, the view does not get updated properly (until you do something like browser window resizing).

I set up a small project, based on the blank project that can be created with the Ionic CLI. You can find it here: https://github.com/christophenne/ionic3-ngIf-problem
Execute npm install and then ionic cordova run browser (you can also run it with the dev server via ionic serve, to verify that everything is fine there).

The basic problem is, that when you go to a page (in the example “page2”) with the NavController push method, and then you go back to the previous page (“home”) via the Browser Back Button, the view does not get updated properly.
Simply click one of the two Select-Buttons (after you came back to “home” via browser-back), and you will see that nothing changes. However, the click-Method is called, as you can see in the Browser console.
Also, as soon as you do something that forces the view to refresh (like resizing the browser window), it finally gets updated.

It’s important for us to have the browser-back, since we don’t use the Ionic-Back-Button and we also want to deploy it as a web app.

It doesn’t work with either ionic 3.4, 3.5 or 3.6. I didn’t try anything lower than that.
Output of ionic info:

global packages:

    @ionic/cli-utils : 1.4.0
    Cordova CLI      : 6.5.0 
    Ionic CLI        : 3.4.0

local packages:

    @ionic/app-scripts : 2.1.3
    Cordova Platforms  : browser 4.1.0
    Ionic Framework    : ionic-angular 3.6.0

System:

    Node       : v6.11.0
    OS         : Linux 3.13
    Xcode      : not installed
    ios-deploy : not installed
    ios-sim    : not installed
    npm        : 3.10.10 


Is there a way to fix this or to work around it ? Thanks in advance.


#2

Update:
When I inject a ChangeDetectorRef and call detectChanges() manually inside the click method, view gets updated.
Like this:

constructor(public navCtrl: NavController,
    private cdr : ChangeDetectorRef) {
}

click(val : number){
    console.log("click(" + val + ")");
    this.selected = val;
    console.log("this.selected = " + this.selected);
    this.cdr.detectChanges();   //this should not be necessary
}

Is there some other way to fix it ?
I don’t think it’s a good solution to go through every single possible event in my whole application, and call detectChanges there - that’s definetly something Angular/Ionic is here for.

I also tried to detach and reattach the ChangeDetectorRef when the component loads, but this doesn’t change anything.

Also, there has got to be a reason why this strange behaviour exactly occurs when you come back to the page with the browser back button. It works fine in every other case.

FYI I also created a github issue for that https://github.com/ionic-team/ionic/issues/12512 . Also, since this one seems to have been closed by accident, here a copy: https://github.com/ionic-team/ionic/issues/12608


#3

You can try with:

import { ApplicationRef } from '@angular/core';
...
    constructor(..., private appRef: ApplicationRef ) {...}
    click(val : number){
        this.selected = val;
        this.appRef.tick();
}

It’s not really better but it force the view to get updated.

Another way is to change the reference of this.selected
In a particular app i’ve used this hack : val = JSON.parse(JSON.stringify(val)); It was for a map.
Maybe you can try number = Number(val.toString()); But i’m not sure that will patch your problem.

Try looking with events from the navController lifeCycle (e.g. ionViewWillEnter)


#4

Thank you for your response.

Unfortunately, none of these helped (except the manual view refresh, which I already posted above - but I think this is not a good general solution - because what do I need a framework with change detection for, if I have to detect changes manually … ).


#5

I found similar symptoms with Windows 10 UWP Ionic app. For instance, *ngif does not work after the page has loaded and there is a dynamic property change from a service - that change is not detected.

Your workaround with ChangeDetectorRef helped to make the change visible.

What also helped is the following:

constructor(private zone: NgZone) {
}

click(val : number){
zone.run(() => {
    console.log("click(" + val + ")");
    this.selected = val;
    console.log("this.selected = " + this.selected);
});
}

Maybe all of it is to do with multithreading and different threads being used on different platforms, and perhaps the scheduler used on browser and Windows platforms is one that is not watched by Angular by default?