-1

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.

vigamage
  • 1,975
  • 7
  • 48
  • 74

2 Answers2

0

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.

Dharman
  • 30,962
  • 25
  • 85
  • 135
AymericFi
  • 140
  • 1
  • 8
  • I understand. But the availability of the network is detected correctly on devices. I get the correct logs on the console when the app is run on a device. It's just, the property is not getting the value assigned. – vigamage Sep 29 '20 at 08:51
  • My advice is to go with tutorials that people know. So that when you encounters an error, there are documentation available online. JoshMorony is known in the Ionic community. – AymericFi Sep 29 '20 at 08:53
  • Sorry if It does not help you directly. – AymericFi Sep 29 '20 at 08:54
  • No, I appreciate it. I added a little edit to the question btw. – vigamage Sep 29 '20 at 08:59
  • Tried using the plugin too. Still the same result. subscription works as expected. property get the value assigned. but the same property does not reflect the change it got in the template – vigamage Oct 01 '20 at 16:55
  • Finally found the solution. It has been a issue with the zone. :) I will answer the question myself – vigamage Oct 02 '20 at 04:15
  • If I may, toggling online inside the callback function of zone is not prioritizing simplicity. Try to place it before if you can, it should not be affected, unless you must do so. – AymericFi Oct 02 '20 at 13:34
0

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

vigamage
  • 1,975
  • 7
  • 48
  • 74