Using Network events to update UI

I’ve been smashing my face against this for too long, and I think I know what the problem is, but not how to fix it yet. I’m trying to use Network and Connection to determine if the device connection is available or not. I subscribed to “Network.onDisconnect()” and “Network.onConnect()”. Which are firing correctly when tested on the device.

The issue comes in when I drop a property on the class to be bound in the view. I’ve tried this about 73 different ways, but I have a feeling the network subscription function isn’t updating the boolean in the Angular2 zone, so the change isn’t detected. Still learning, and Angular2 zones are still over my head at this point…

The most simple example is this (ignore my inconsistent conventions) ;):

import { Network, Connection } from 'ionic-native';
// ...other imports...

@Page(...)
export class SomePage {
    private _disconnectSub: any;
    private _connectSub: any;
    public hasConnection: boolean = false;

    constructor(platform: Platform) {
        this._platform.ready().then(res => {
            // Bind to the Network events, and set the initial value of the bool
            this._disconnectSub = Network.onDisconnect().subscribe(this.onNetworkDisconnect);
            this._connectSub = Network.onConnect().subscribe(this.onNetworkConnect);
            this.hasConnection = Network.connection != Connection.NONE;
        });
    }

    private onNetworkDisconnect() : void {
	this.hasConnection = false;
	console.log('Connection lost!', this.hasConnection, Network.connection);
    }
	
    private onNetworkConnect() : void {
	let self = this;
	setTimeout(function () {
	    self.hasConnection = Network.connection != Connection.NONE;
	    console.log('Connection restored!', self.hasConnection, Network.connection);
	}, 2000);
    }
}

The view’s HTML has something simple like this:
<p>{{ hasConnection }}</p>

The above renders as “true” on the page when the app loads. When testing on my device, if I turn on airplane mode, I get the right console.log messages, but “hasConnection” never changes in the UI.

1 Like

Fixed! The solution:

The constructor code is now something like this:

constructor(private _ngZone: NgZone)
{ 
    this._platform.ready().then(x => {
        this._disconnectSub = Network.onDisconnect().subscribe(x => {
            _ngZone.run(() => {  this.onNetworkDisconnect(); });
        });

        this._connectSub = Network.onConnect().subscribe(x => {
            _ngZone.run(() => { this.onNetworkConnect(); });
        });

        this._hasConnection = Network.connection != Connection.NONE;
    });
}

I tried using NgZone inside the callback functions, but that didn’t work. I had to run the function itself within NgZone because the Network events are running outside Angular2’s zone.

Now my “Connection lost” UI element correctly shows and hides when I turn on and off airplane mode! Yey! :smiley:

5 Likes

Hello Kizmar. Do you have one that use ionic-native to keep on listening on the network connectivity?

Best Regards

Hello Kizmar. Do you have one that use ionic-native to keep on listening on the network connectivity? Specifically ionic 2 on the background mode? Thanks

Best Regards
[/quote]

Hello, why is it displaying an alert on the web but not on an android device? Best Regardfs

onConnect().subscribe(() => {
console.log(‘network connected!’);
// We just got a connection but we need to wait briefly
setTimeout(() => {
if (Network.type !== ‘none’) {
console.log(‘we got a wifi connection, woohoo!’);
let alert = this.alertCtrl.create({
subTitle: ‘Connection’,
buttons: [‘Dismiss’]
});
alert.present();
}
}, 3000);
});

Best answer ever. Thanks for sharing!

Thank you so much for this solution. Still getting used to Ionic 3.

You should not have to manually interact with zones.

private onNetworkConnect() : void {
let self = this;
setTimeout(function () {
self.hasConnection = Network.connection != Connection.NONE;
console.log(‘Connection restored!’, self.hasConnection, Network.connection);
}, 2000);
}

First thing i can’t import connection. 2nd thing is that I tried with Network.type instead of connection but inside the setInterval the network .type is not taken . Throwing the following error
main.js:1444 ERROR TypeError: Cannot read property ‘type’ of undefined
at main.js:48105
at t.invokeTask (polyfills.js:3)
at Object.onInvokeTask (main.js:4500)
at t.invokeTask (polyfills.js:3)
at r.runTask (polyfills.js:3)
at invoke (polyfills.js:3)
at n (polyfills.js:2)

Awesome, it’s working now!