npm.io
22.0.0 • Published 1 month ago

ngx-connection-service

Licence
MIT
Version
22.0.0
Deps
1
Size
47 kB
Vulns
0
Weekly
0
Stars
5

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 --save

Server-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 NgModule setup: ConnectionServiceModule is still available and works, but is deprecated. Prefer provideConnectionService() above.

import {NgModule} from '@angular/core';
import {ConnectionServiceModule} from 'ngx-connection-service';

@NgModule({
  imports: [ConnectionServiceModule],
})
export class AppModule {
}
  • Inject ConnectionService using inject() (or the constructor) in your component.
  • Read the reactive state Signal, or subscribe to monitor() 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 uses provideZonelessChangeDetection(); tests use RxJS TestScheduler virtual time instead of fakeAsync/tick.
  • Standalone-first API: provideConnectionService() replaces ConnectionServiceModule for ApplicationConfig / bootstrapApplication setups. ConnectionServiceModule is kept for backward compatibility but is deprecated.
  • ConnectionService now exposes a reactive state Signal in addition to the existing monitor() Observable API (dual API, non-breaking).
  • Demo application converted to standalone components using the new @if control-flow syntax and inject().
  • 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.js has been removed entirely. The application and library now run zoneless via provideZonelessChangeDetection(); zone.js is only an optional peer of @angular/core and is not installed.
  • Angular runtime/build packages are intentionally pinned to latest 22.x (not 23+) to maintain declared Angular 22 compatibility for this release line.
  • @angular/cli 22 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)

Keywords