ngx-connection-service
v22.0.0
Published
Detects whether browser has an active internet connection or not in Angular application.
Readme
Internet Connection Monitoring Service
Detects whether browser has an active internet connection or not in Angular application.
This library is a fork of https://github.com/ultrasonicsoft/ng-connection-service by Balram Chavan.
Install
npm i ngx-connection-service --saveServer-Side Rendering (SSR)
No extra dependencies are required for Angular Universal / SSR. On the server, the service uses a Window stub with navigator.onLine = true and logs a console warning. Online/offline DOM events are only active in the browser after hydration.
Angular Version Compatibility
Please use following table to determine suitable library version for your Angular project.
| ngx-connection-service version | Angular version | |----------------------------------|-------------------| | 7.0.x | 7.2.16 | | 8.0.x | 8.2.14 | | 9.0.x | 9.1.13 | | 10.0.x | 10.2.5 | | 11.0.x | 11.2.14 | | 12.0.x | 12.2.17 | | 13.0.x | 13.4.0 | | 14.0.x | 14.3.0 | | 15.0.x | 15.2.9 | | 16.0.x | 16.1.8 | | 17.0.x | 17.1.0 | | 18.0.x | 18.1.2 | | 19.0.x | 19.2.25 | | 20.0.x | 20.3.27 | | 21.0.x | 21.2.20 | | 22.0.x | 22.1.2 |
Usage
- Register
provideConnectionService()in your application's providers (standalone /ApplicationConfig).
import {ApplicationConfig} from '@angular/core';
import {provideConnectionService} from 'ngx-connection-service';
export const appConfig: ApplicationConfig = {
providers: [
provideConnectionService(),
],
};import {bootstrapApplication} from '@angular/platform-browser';
import {AppComponent} from './app/app.component';
import {appConfig} from './app/app.config';
bootstrapApplication(AppComponent, appConfig)
.catch(err => console.error(err));Legacy
NgModulesetup:ConnectionServiceModuleis still available and works, but is deprecated. PreferprovideConnectionService()above.import {NgModule} from '@angular/core'; import {ConnectionServiceModule} from 'ngx-connection-service'; @NgModule({ imports: [ConnectionServiceModule], }) export class AppModule { }
- Inject
ConnectionServiceusinginject()(or the constructor) in your component. - Read the reactive
stateSignal, or subscribe tomonitor()for push notifications whenever the connection status changes. Both APIs are kept in sync (dual API).
import { Component, inject } from '@angular/core';
import { ConnectionService } from 'ngx-connection-service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
private readonly connectionService = inject(ConnectionService);
// Signal API (recommended for modern, signal-based Angular apps)
readonly currentState = this.connectionService.state;
constructor() {
// Observable API (still fully supported)
this.connectionService.monitor().subscribe(currentState => {
console.log(currentState);
});
}
}
In the template you can then read the Signal directly:
@if (currentState().hasNetworkConnection && currentState().hasInternetAccess) {
<span>ONLINE</span>
} @else {
<span>OFFLINE</span>
}Configuration
You can configure the service using ConnectionServiceOptions configuration variable.
Following options are available;
/**
* Instance of this interface could be used to configure "ConnectionService".
*/
export interface ConnectionServiceOptions {
/**
* Controls the Internet connectivity heartbeat system. Default value is 'true'.
*/
enableHeartbeat?: boolean;
/**
* Url used for checking Internet connectivity, heartbeat system periodically makes "HEAD" requests to this URL to determine Internet
* connection status. Default value is "//api.ipify.org/".
*/
heartbeatUrl?: string;
/**
* Callback function to used for executing heartbeat requests. Defaults to HttpClient.request(...) function.
*/
heartbeatExecutor?: (options?: ConnectionServiceOptions) => Observable<any>;
/**
* Interval used to check Internet connectivity specified in milliseconds. Default value is "30000".
*/
heartbeatInterval?: number;
/**
* Interval used to retry Internet connectivity checks when an error is detected (when no Internet connection). Default value is "1000".
*/
heartbeatRetryInterval?: number;
/**
* HTTP method used for requesting heartbeat Url. Default is 'get'.
*/
requestMethod?: 'get' | 'post' | 'head' | 'options';
}You should provide ConnectionServiceOptions via provideConnectionService(options) as follows;
import {ApplicationConfig} from '@angular/core';
import {ConnectionServiceOptions, provideConnectionService} from 'ngx-connection-service';
export const appConfig: ApplicationConfig = {
providers: [
provideConnectionService({
enableHeartbeat: false,
heartbeatUrl: '/assets/ping.json',
requestMethod: 'get',
heartbeatInterval: 3000
} satisfies ConnectionServiceOptions),
],
};Custom HeartBeat handling function
You could use a callback function for handling heartBeat requests by defining heartbeatExecutor property in ConnectionServiceOptions;
import { Component, inject } from '@angular/core';
import { ConnectionService } from 'ngx-connection-service';
import {Observable} from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
private readonly connectionService = inject(ConnectionService);
readonly currentState = this.connectionService.state;
constructor() {
this.connectionService.updateOptions({
heartbeatExecutor: options => new Observable<any>(subscriber => {
if (Math.random() > .5) {
subscriber.next();
subscriber.complete();
} else {
throw new Error('Connection error');
}
})
});
}
}
Testing your own code that uses ConnectionService
ConnectionService uses RxJS timer()/debounceTime() internally (heartbeat polling, retry delay, and state
debouncing). If you write unit tests that need to wait for these internal delays, you don't need zone.js's
fakeAsync/tick. Instead, provide ConnectionServiceSchedulerToken with an RxJS TestScheduler
(from rxjs/testing) and advance its virtual clock synchronously:
import {TestBed} from '@angular/core/testing';
import {TestScheduler} from 'rxjs/testing';
import {ConnectionService, ConnectionServiceSchedulerToken} from 'ngx-connection-service';
const scheduler = new TestScheduler(() => {});
TestBed.configureTestingModule({
providers: [
ConnectionService,
{provide: ConnectionServiceSchedulerToken, useValue: scheduler},
// ...your other providers (e.g. provideHttpClient, provideHttpClientTesting)
],
});
const service = TestBed.inject(ConnectionService);
// Advance virtual time by 300ms synchronously instead of really waiting:
scheduler.maxFrames = scheduler.frame + 300;
scheduler.flush();This keeps tests instantaneous and fully zoneless. ConnectionServiceSchedulerToken is optional — when not
provided, the service defaults to RxJS's regular asyncScheduler (real timers), which is what you want in production.
Changes
- Zoneless: the demo application and library tests no longer depend on
zone.js. The app usesprovideZonelessChangeDetection(); tests use RxJSTestSchedulervirtual time instead offakeAsync/tick. - Standalone-first API:
provideConnectionService()replacesConnectionServiceModuleforApplicationConfig/bootstrapApplicationsetups.ConnectionServiceModuleis kept for backward compatibility but is deprecated. ConnectionServicenow exposes a reactivestateSignal in addition to the existingmonitor()Observable API (dual API, non-breaking).- Demo application converted to standalone components using the new
@ifcontrol-flow syntax andinject(). - This version use https://api.ipify.org/ to determine Internet connection status
- Removed dependency to "ssr-window" package
Security / Dependency Status
Upgrade Matrix (current tree)
| Package group | Previous range | Current range | Decision |
|---------------|----------------|---------------|----------|
| Angular runtime (@angular/*) | ^21.2.20 | ^22.1.2 | Upgraded to latest 22.x runtime patches. |
| Angular build chain (@angular-devkit/build-angular, @angular/cli, @angular/compiler-cli, @angular/language-service, ng-packagr) | 21.x | 22.x | Upgraded to latest Angular 22 tooling patches. |
| Lint stack (angular-eslint, eslint, @eslint/js, @typescript-eslint/*, typescript-eslint) | Angular-eslint 21.4.0 | Angular-eslint 22.1.0 + ESLint 10.x companions | Upgraded to latest Angular 22-compatible lint toolchain. |
| Type defs (@types/node, @types/jasmine) | previous majors | Latest Node/Jasmine types compatible with current toolchain | Retained at latest compatible versions. |
| Test UI reporter (karma-jasmine-html-reporter, jasmine-core) | 2.1.0 / 5.1.x | 2.2.0 / 6.3.x | Upgraded to latest compatible versions. |
| TypeScript toolchain (typescript) | ~5.9.3 | ~6.0.3 | Upgraded to satisfy Angular 22 peer requirements. |
| Overrides (less, uuid, webpack-dev-server) | Fixed versions in overrides | removed | Removed; now resolved by upstream transitive graph. |
| E2E stack (protractor, jasmine-spec-reporter, ts-node) | present | removed | Fully removed from current tree. |
Exceptions (latest-version policy with Angular 22 compatibility)
zone.jshas been removed entirely. The application and library now run zoneless viaprovideZonelessChangeDetection();zone.jsis only an optional peer of@angular/coreand is not installed.- Angular runtime/build packages are intentionally pinned to latest
22.x(not23+) to maintain declared Angular 22 compatibility for this release line. @angular/cli22 requires Node.js^22.22.3 || ^24.15.0 || >=26.0.0; run with a matching Node patch version before executing Angular CLI commands.- If a dependency cannot move to its global latest version without breaking Angular 22 peer constraints, it is pinned to the highest Angular 22-compatible release.
License
MIT License © Argela Inc. & Balram Chavan (orginal work)
