Ionic 3 network connectivity check how to implement for all pages (components)?


#13

But Vibin i need this functionality all through pages …


#16

@anespa please call the method initializeApp() inside constructor.This is your error now


#17

Try with:

constructor(private platform: Platform, 
            private statusBar: StatusBar, 
            private splashScreen: SplashScreen) {
    ...
}

#18

Hi, your code is working on me. But, how can I reload the view whenever the network changes?


#19

what if I have wifi connection but no Internet connectivity?
How can I check that???


#20

Do an http request to www.google.com with a timeout


#21

Just a small tip.The network not always could be trusted as stable, so I would do something like this (setTimeout).
So I could make sure that I have a stable network in 3 seconds before I could pass it as online.
Sometimes the app could so slow so the network indicate you’re online but was offline just because the network was so quick to switch to offline. That really mess things up for me once. But this small tip should avoid that.
Network.ts


import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AlertController, Events } from 'ionic-angular';
import { Network } from '@ionic-native/network';

/*
  Generated class for the NetworkProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
export enum ConnectionStatusEnum {
    Online,
    Offline
}
@Injectable()
export class NetworkProvider {

  constructor(public http: HttpClient,
              public alertCtrl: AlertController, 
              public network: Network,
              public eventCtrl: Events) {
    console.log('Hello NetworkProvider Provider');
    this.previousStatus = ConnectionStatusEnum.Online;
  }

  public initializeNetworkEvents(): void {
        this.network.onDisconnect().subscribe(() => {
            if (this.previousStatus === ConnectionStatusEnum.Online) {
                this.eventCtrl.publish('network:offline');
            }
            this.previousStatus = ConnectionStatusEnum.Offline;
        });
        this.network.onConnect().subscribe(() => {
           setTimeout(() => {
            if (this.previousStatus === ConnectionStatusEnum.Offline) {
                this.eventCtrl.publish('network:online');    
            }
            this.previousStatus = ConnectionStatusEnum.Online;
             }, 3000);
        });
    }

}

#22

I would also like some help here. I followed what you did @addwebsolution but it doesn’t work. The app is not crashing but it does nada when I turn Internetz on and off.

  • I have the ionic cordova network plugin installed
  • Installed Network
  • Imported it to app.module.ts

network.ts

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

//Ionic
import { Events } from 'ionic-angular'

//Ionic Native
import { Network } from '@ionic-native/network'

/*
  This provider checks network connection on the platform and publishes an enum to online or offline state
*/

export enum ConnectionStatus {
  Online,
  Offline
}

@Injectable()
export class NetworkProvider {

  public previousStatus

  constructor(
    public network: Network,
    public events: Events
  ) {
    this.previousStatus = ConnectionStatus.Online;
  }
  
  /* BOOTS a listener on the network */
  public initializeNetworkEvents(): void {

    /* OFFLINE */
    this.network.onDisconnect().subscribe(() => {
      if(this.previousStatus === ConnectionStatus.Online) { 
        this.events.publish('network:offline') 
        this.previousStatus = ConnectionStatus.Offline
      }
    })

    /* ONLINE */
    this.network.onConnect().subscribe(() => {
      if(this.previousStatus === ConnectionStatus.Offline) { 
        this.events.publish('network:online') 
        this.previousStatus = ConnectionStatus.Online
      }
    })

  }

  public getNetworkType(): string {
    return this.network.type
  }



}

app.component.ts

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

//Ionic
import { Platform, Events } from 'ionic-angular';

//Ionic Native
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

//Pages
import { LoginPage } from '../pages/login/login';

//Providers
import { NetworkProvider } from '../providers/network/network'

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage:any = LoginPage;

  constructor( 
    public statusBar: StatusBar, 
    public splashScreen: SplashScreen,
    public platform: Platform,
    public networkStatus: NetworkProvider,
    public events: Events
  ) {

    this.platform.ready().then(() => {
      
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      
      this.initializeApp()
    });
  }

  initializeApp(): void {
    /* Check networkStatus */
    this.networkStatus.initializeNetworkEvents()
    this.events.subscribe('network:offline', () => {
      console.log('network:offline ==> ' + this.networkStatus.getNetworkType())
    })
    this.events.subscribe('network:online', () => {
      console.log('network:online ==> ' + this.networkStatus.getNetworkType())
    }) 

    /* Ionic stuff */
    this.statusBar.styleDefault();
    this.splashScreen.hide();
  }

}



#23

Add

getNetworkStatus(): Observable

:wink:

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

import { Events } from 'ionic-angular'

import { Network } from '@ionic-native/network'

import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';

export enum ConnectionStatus {
    Online,
    Offline
}

@Injectable()
export class NetworkService {

    public status: ConnectionStatus;
    private _status: BehaviorSubject<ConnectionStatus> = new BehaviorSubject(null);

    constructor(
        public network: Network,
        public events: Events
    ) {
        this.status = ConnectionStatus.Online;
    }

    public initializeNetworkEvents(): void {

        /* OFFLINE */
        this.network.onDisconnect().subscribe(() => {
            if (this.status === ConnectionStatus.Online) {
                this.setStatus(ConnectionStatus.Offline);
            }
        })

        /* ONLINE */
        this.network.onConnect().subscribe(() => {
            if (this.status === ConnectionStatus.Offline) {
                this.setStatus(ConnectionStatus.Online);
            }
        })

    }

    public getNetworkType(): string {
        return this.network.type
    }

    public getNetworkStatus(): Observable<ConnectionStatus> {
        return this._status.asObservable();
    }
    
    private setStatus(status: ConnectionStatus) {
        this.status = status;
        this._status.next(this.status);
    }
}


Binding to service property needs page refreshing!
#24

Will test this as soon as I get my hands on it again. Thanks!


#25

Congrats, best practice…


#26

Dear Friends, I have an Error: StaticInjectorError(AppModule)[NetworkProvider -> Network]:
StaticInjectorError(Platform: core)[NetworkProvider -> Network]:
NullInjectorError: No provider for Network!

Thanking you


#27

Hope this will help


#28

It’s a nice solution! Thanks!
But i have a problem when i need to check network status on app boot, it’s always returns null.

Here is my code:

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { NetworkProvider } from '../providers/network/network';
import { NgZone } from '@angular/core';

@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  rootPage: any = 'LoginPage';
  isOffline: boolean;

  constructor(
    platform: Platform,
    statusBar: StatusBar,
    splashScreen: SplashScreen,
    public networkProvider: NetworkProvider,
    public ngZone: NgZone
  ) {
    platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      statusBar.styleDefault();
      splashScreen.hide();
      statusBar.backgroundColorByHexString('#f6f6f6');
      this.networkProvider.initializeNetworkEvents();
      this.checkNetwork();
    });
  }

  showOfflineAlert(data) {
    this.ngZone.run(() => {
      this.isOffline = !!data;
    });
  }

  checkNetwork() {
    this.networkProvider.getNetworkStatus().subscribe(data => {
      console.log('platform ready', data);
      this.showOfflineAlert(data);
    });
  }
}

Any thoughts guys? =D


#29

Cute code for sure. Unfortunately doesn’t work at all for me. Never enters subscription events whenever I close or open my wifi connection on my PC. I’m running Windows 10.

UPDATE : this works perfectly fine on an Android device. Just not in a Chrome browser in Windows 10.

Ionic infos :

ionic (Ionic CLI) : 4.1.2
Ionic Framework : ionic-angular 3.9.2
@ionic/app-scripts : 3.2.0
cordova (Cordova CLI) : 8.1.1 (cordova-lib@8.1.0)
Cordova Platforms : none
Cordova Plugins : no whitelisted plugins (1 plugins total)
NodeJS : v10.9.0
npm : 6.2.0
OS : Windows 10

Here’s my code (after applying latest suggestions in the thread) :

networkService.ts

import { Injectable } from '@angular/core';
import { Events } from 'ionic-angular'
import { Network } from '@ionic-native/network'
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';

export enum ConnectionStatus {
    Online,
    Offline
}

@Injectable()
export class NetworkService {

    public status: ConnectionStatus;
    private _status: BehaviorSubject<ConnectionStatus> = new BehaviorSubject(null);

    constructor(
        public network: Network,
        public events: Events
    ) {
        this.status = ConnectionStatus.Online;
    }

    public initializeNetworkEvents(): void {

        console.log('Subscribe to onDisconnect events');
        /* OFFLINE */
        this.network.onDisconnect().subscribe(() => {
            if (this.status === ConnectionStatus.Online) {
                this.setStatus(ConnectionStatus.Offline);
            }
        })

        console.log('Subscribe to onConnect events');
        /* ONLINE */
        this.network.onConnect().subscribe(() => {
            if (this.status === ConnectionStatus.Offline) {
                this.setStatus(ConnectionStatus.Online);
            }
        })

    }

    public getNetworkType(): string {
        return this.network.type
    }

    public getNetworkStatus(): Observable<ConnectionStatus> {
        return this._status.asObservable();
    }

    private setStatus(status: ConnectionStatus) {
        this.status = status;
        this._status.next(this.status);
    }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';
import { Network } from '@ionic-native/network';

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { NetworkService } from './providers/networkService';

@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [
    Network,
    NetworkService,
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler}
  ]
})
export class AppModule {}

app.components.ts

import { Component } from '@angular/core';
import { Platform, ToastController } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

import { HomePage } from '../pages/home/home';
import { NetworkService } from './providers/networkService';

@Component({
  templateUrl: 'app.html'
})

export class MyApp {
  rootPage:any = HomePage;

  constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen,
    public networkService: NetworkService,
    public toast: ToastController,) {
      
    platform.ready().then(() => {

      this.initializeApp();

      statusBar.styleDefault();
      splashScreen.hide();
    });
  }

  initializeApp(): void {

    this.networkService.initializeNetworkEvents();

    this.networkService.getNetworkStatus().subscribe(data => {
      console.log('platform ready', data);
      this.toast.create ({
        message: data + ' ' +  this.networkService.getNetworkType(),
        duration: 3000,
      }).present();;
    });
  }

}

I debug with Chrome and see the network subscription inside the provider (onConnect() and onDisconnect()) but they never get raised. Any idea why ?


#30

Application reference allows

  • allows to invoke application-wide change detection by calling appRef.tick()
  • it allows to add/remove views to be included in or excluded from change detection using attachView() and detachView()
  • provides a list of registered components and component types using componentTypes and components and some other change detection related information

Use the following code works perfectly fine for me. I have created a shared provider which is accessed by all the pages in the app.
Step 1: Import the

import { Component, ViewChild,ApplicationRef } from '@angular/core';

Application Ref
Step 2:
public applicationRef: ApplicationRef, in the constructor
Step 3: Run the following function when platform ready

   {
       this.network.onDisconnect().subscribe(() => {
      this.connectedToInternet = false;
     // this.isConnectedObserver.next(this.connectedToInternet);
        this.applicationRef.tick();
      // alert("INTERNET DISCONNECTED");
        console.log("INTERNET DISCONNECTED", this.connectedToInternet);
        
    });

    this.network.onConnect().subscribe(() => {
        
     this.connectedToInternet=true;
   // this.isConnectedObserver.next(this.connectedToInternet);
    this.applicationRef.tick();
    // alert("INTERNET CONNECTED.Please wait...INITIALIZING...Please upload the unsaved local data if any. ");
    // window.location.reload();
      console.log("INTERNET  CONNECTED", this.connectedToInternet);

     });
   }

#31

Worked For me Thank You


#32

Hi,Here i have attached github link for Check InterNet connection,You refer this coding but you can add some coding for condition check and push some page or sow msg something…i have attached sample application only.May be its work correctly,please try it.


Please refer this coding and try it.


#33

This is the best I came up with, works for browser and for devices, uses RxJs 6, please be aware of that.
Just inject the server where you need to check, or if you wish to check on app.html inject in the app.component.ts:

import {
  Injectable
} from '@angular/core';
import {
  Network
} from '@ionic-native/network';

import {
  Platform
} from 'ionic-angular';

import {
  Observable,
  fromEvent,
  merge,
  of
} from 'rxjs';

import {
  mapTo
} from 'rxjs/operators';

@Injectable()
export class NetworkService {

  private online$: Observable < boolean > = null;

  constructor(private network: Network, private platform: Platform) {
    this.online$ = Observable.create(observer => {
      observer.next(true);
    }).pipe(mapTo(true));
    
    if (this.platform.is('cordova')) {
      // on Device
      this.online$ = merge(
        this.network.onConnect().pipe(mapTo(true)),
        this.network.onDisconnect().pipe(mapTo(false)));
    } else {
      // on Browser
      this.online$ = merge( of (navigator.onLine),
        fromEvent(window, 'online').pipe(mapTo(true)),
        fromEvent(window, 'offline').pipe(mapTo(false))
      );
    }
  }

  public getNetworkType(): string {
    return this.network.type
  }

  public getNetworkStatus(): Observable < boolean > {
    return this.online$;
  }

}

Then on your component you do something like this:

...
public isConnected:boolean = true;
...
constructor(public networkService: NetworkService){
    this.networkService.getNetworkStatus().subscribe((connected: boolean) => {
      this.isConnected = connected;
    });

}

I hope this can help someone.


#34

I have the network plugin working perfect I’m the devapp but nothing fires in a real ipa build. What version of ionic and the plugin are you using? Thanks