Network state on initial load, if no changes happened

#1

Hi,

i write an NetworkProvider for check the Network

@Injectable()
export class NetworkService {
	private networkType: string;

	constructor(private network: Network, private platform: Platform) {
	}

	init() {
		if (this.platform.is('cordova')) {
			this.network.onDisconnect().subscribe(() => {
				this.networkType = undefined;
			});
			this.network.onConnect().subscribe(() => {
				this.networkType = this.network.type;
			});
		}
		else {
			this.networkType = 'dev';
		}
	}

	getNetworkType(): string {
		return this.networkType;
	}

	isConnected(): boolean {
		return this.networkType !== undefined;
	}
}

and the init method is called by the constructor of the app.component

this.platform.ready().then(() => {
        ...
	this.networkService.init();
        ...
});

The Problem is when I load the app, the function “isConnected” returns always false.
it returns true, if I close the connection and open it again.

There is no change at initialization, so no methods are called for any subscribe. But I still wants to know the current connection status when the app is loading

#2

@YuEmAz The problem with your code is that you have an asynchronous code to determine the initial network state, while the isConnected() method is synchronous, meaning that it could return before the initial connection state is defined.

To avoid such an undesirable behaviour, I advise you to emit network changes and only return in the function isConnected() after the first event is sent.

Here is my service to handle that (the code is a bit changed from the one that I use, but should work):

import { Injectable } from '@angular/core';
import { Network } from '@ionic-native/network';
import { Platform } from 'ionic-angular';
import { take } from 'rxjs/operators';
import { Observable, ReplaySubject } from 'rxjs/Rx';

@Injectable()
export class NetworkService {
	
	private changed = false;
	private connected = false;
	private connectedSubject$ = new ReplaySubject<void>(1);
	private disconnectedSubject$ = new ReplaySubject<void>(1);
	private connectionChangedSubject$ = new ReplaySubject<boolean>(1);
	
	public connected$: Observable<void> = this.connectedSubject$.asObservable();
	public disconnected$: Observable<void> = this.disconnectedSubject$.asObservable();
	public connectionChanged$: Observable<boolean> = this.connectionChangedSubject$.asObservable();

	constructor(
		private network: Network,
		private platform: Platform,
	) {
		this.init();
	}

	private init(): void {
		this.connected$.subscribe(() => this.connectionChanged(true));
		this.disconnected$.subscribe(() => this.connectionChanged(false));

		this.platform.ready().then(() => this.platform.is('cordova')).then(native => {
			if (native) {
				this.network.onDisconnect().subscribe(() => {
					this.disconnectedSubject$.next(null);
				});
				
				this.network.onConnect().subscribe(() => {
					this.connectedSubject$.next(null);
				});
			} else {
				let fnConnected = () => {
					let connected = navigator.onLine;
					let subject$ = connected ? this.connectedSubject$ : this.disconnectedSubject$;
					subject$.next(null);
				};

				fnConnected();

				setInterval(() => fnConnected(), 500);
			}
		});

		setTimeout(() => {
			if (!this.changed) {
				this.connectedSubject$.next(null);
			}
		}, 5000);
	}

	private connectionChanged(connected: boolean) {
		if ((connected !== this.connected) || !this.changed) {
			this.changed = true;
			this.connected = connected;
			this.connectionChangedSubject$.next(connected);
		}
	}

	public isConnected(): Promise<boolean> {
		return new Promise<boolean>((resolve, reject) => {
			this.connectionChanged$.pipe(take(1)).subscribe(
				connected => resolve(connected),
				error => reject(error),
			);

			if (this.changed) {
				resolve(this.connected);
			}
		});
	}
}

Then you can check if the network is connected with:

this.networkService.isConnected().then(connected => {
    // do something
});

If you want to listen to connection changes you can do the following:

this.networkService.connectionChanged$.subscribe(connected => {
    // do something
});