stop working after restarting angular server
mohammadtetouan opened this issue · comments
stop working after restarting angular server
and it never work again
weird. I will check it out.
You could write this in a more rxjs-ish way. Instead of new Observable
you can use merge and fromEvent
import {fromEvent, merge} from 'rxjs';
import {mapTo} from 'rxjs/operators';
this.connectionMonitor = merge(
fromEvent(window, 'offline').pipe(mapTo(false)),
fromEvent(window, 'online').pipe(mapTo(true))
);
One problem with the current version is that it never emits any value as long as the state is online or offline. What I wanted in my application is that the subscriber always gets the latest state.
Here a solution that always emits at least one value and each subscriber receives the latest state
import {fromEvent, merge} from 'rxjs';
import {mapTo, shareReplay, startWith} from 'rxjs/operators';
this.connectionMonitor =
merge(
fromEvent(window, 'offline').pipe(mapTo(false)),
fromEvent(window, 'online').pipe(mapTo(true))
)
.pipe(
startWith(window.navigator.onLine),
shareReplay(1)
);
This does not solve the problem of the online
state. online
does not mean that you are connected to the Internet it only says that your device has a connection to the next router. One way to detect if the device is really online, is to send a request to your back end and check the response.
https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine
Here an example that sends a http request whenever the connectivity state changes to online
In this example the endpoint /ping
sends back a 1
in the response body
const onlineCheck$ = this.httpClient.get('ping', {responseType: 'text'})
.pipe(
map(response => response === '1'),
catchError(_ => of(false))
);
this.connection$ =
merge(
fromEvent(window, 'offline').pipe(mapTo(false)),
fromEvent(window, 'online').pipe(mapTo(true))
)
.pipe(
startWith(window.navigator.onLine),
switchMap(flag => flag ? onlineCheck$ : of(false)),
shareReplay(1)
);
This solution unfortunately also does not really solve all the problems. For example, when the router, your device is connected to, loses the Internet connection. The browser still reports online
and does not emit any state change.
Hi
That's great. Thanks for your work.
There are only two things I would change.
According to the specification if navigator.onLine returns false the browser is definitely offline
Returns false if the user agent is definitely offline (disconnected from the network). Returns true if the user agent might be online.
According to this I would remove the network check in case of the offline event
this.offlineSubscription = fromEvent(window, 'offline').subscribe(() => {
this.currentState.hasNetworkConnection = false;
// this.checkInternetState(); <---- These requests will always fail
this.currentState.hasInternetAccess = false; <---- User agent is definitely offline
this.emitEvent();
});
The second thing I would change is removing the dependency on lodash. Not because it's a bad library, but because the two functions _.clone
and _.defaults
can easily be replaced with the spread operator.
return _.clone(this.serviceOptions);
becomes
return {...this.serviceOptions};
and
this.serviceOptions = _.defaults({}, options, this.serviceOptions);
becomes
this.serviceOptions = { ...this.serviceOptions, ...options };
and _.isNil
is just a comparison with null
if (!_.isNil(this.httpSubscription)) {
------> if (this.httpSubscription != null) {
Hi,
Thanks for the comments, for the first one, if our network access is broken then definitely our Internet access will also be broken but, there is one particular case where heartbeat check may work even though machine has no network access. This could happen when the application is served from localhost (actually during development) and heartbeat url was configured as the local resource (like the one in the sample checking for "/assets/ping.json" file). In this case library will report for no network access but heartbeat still returns true because we could access our local machine. As a result of this case, I decided to leave the network and heartbeat checks independent from each other.
For the second one, you are right about the lodash dependency which I added to project. Actually I had problems with spread operator before and not using it much and I think "isNil" function is much safer than only "null" comparisons (which is actually sufficient for this case). Thus as a habit I prefer to use lodash functions. Of course it can be removed from the library.
@yildiraymeric @ralscha @mohammadtetouan
I have removed the "lodash" dependency from the library.
Package has been updated and released on NPM. Please refer to the latest version supporting Angular v9-v15.