Changes to the property not appearing in template on real device

65 views Asked by At

In my Ionic 5 app, I am going to show users an overlay with some text on it when the internet connection is not available.

I have following function to detect if the internet is available or not.

checkOnline$(): Observable<boolean> {
    return merge(
      of(navigator.onLine),
      fromEvent(window, 'offline').pipe(mapTo(false)),
      fromEvent(window, 'online').pipe(mapTo(true)),
      );
}

Inside my constructor, I call above function.

this.checkOnline$().subscribe(isOnline => {

  if (!isOnline) {
    console.log('>>>>>> offLine');
    this.online = false;
  } else {
    console.log('>>>>>> online');
    this.online = true;
  }
  console.log('>>>>>> ##### this.online = ', this.online)
      
});

The property online is used in the template to show or hide the overlay depending on the availability of internet.

<div id="offline-overlay" *ngIf="!online" class="center-vertically">
    <div id="offline-overlay-text" class="center-content">
      <span>ABCD EFGH IJKL</span>
    </div>
</div>

Above setup is working fine. I get all console logs as expected and overlay is correctly shown or hidden according to the availability of wifi. BUT ON BROWSER ONLY.

When I push the app to a device, it does not work. To check if the property online is assigned the correct values, I tried printing it in the template.

{{online}}

No, it does not get the correct value. but in the browser, it does get the correct value.

I debugged the app installed to the device to check the console logs. Those are logged as expected.

Why is this?

Why different behaviors on browsers and devices?

How can I fix this.

Thanks in advance.

EDIT:

I added logs to check if the property online gets the correct value assigned. It does get the correct value when run on the device. Now it's just that the template not getting that value.

2

There are 2 answers

0
vigamage On BEST ANSWER

Found the solution.

It turned out that the code inside the subscription breaks out of Angular Zone.

I did following to fix the issue.

this.checkOnline$().subscribe(isOnline => {
      console.log('************* isonline = ', isOnline);
      if (isOnline) {
        console.log('>>>>>> online');

        this.zone.run(() => {
          this.isOffline = false;
          this.globalDataService.setAppOnline();
        });

      } else {
        console.log('>>>>>> offline');

        this.zone.run(() => {

          this.isOffline = true;
          this.globalDataService.setAppOffline();

        });

      }
}); 

Thanks to this answer:

https://stackoverflow.com/a/36919459/3892439

7
Sentida On

JoshMorony describes how to make a “Connectivity” service in this tutorial: http://www.joshmorony.com/creating-an-advanced-google-maps-component-in-ionic-2/ 2.8k. (part III)

It detects whether it is running on a device or through the browser and uses the best method for checking Internet connectivity.

Otherwise I do suggest to check Ionic Object directly such as: https://ionicframework.com/docs/native/network instead of window object that are browser related instead of the native mobile component.