37

How I would check internet connection in Angular2 at the time of API hitting, whenever in my app API is hit to server sometimes user is offline (i mean without internet connection) so how would i check the internet connectivity ? is there some special status code for internet connectivity ? or something else ?

PS:- i found navigator.onLine in angularJs but seems not working in angular2.

update

as sudheer suggested in answer below navigator.onLine in working with angular2 but still not working properly why ? working example here

1
  • 5
    I checked this with Windows 10 and Chrome. It always return 'true', if at least one network adapter is connected. So if you have installed a virtual adapter, like the "HostOnly-Network" from VirtualBox, you always get 'true', until you disable this too. :( Commented Apr 12, 2017 at 18:37

9 Answers 9

46

(2018) Code updated for rxjs6

It totally works with angular2. Obviously it's different from angularJS because neither $scope nor $apply exist anymore. RxJS makes this easy, though! Tested on Chrome 53:

template:

<p>{{online$ | async}}</p>

component:

import { Observable, fromEvent, merge, of } from 'rxjs';
import { mapTo } from 'rxjs/operators';

@Component({ /* ... */ })
export class MyComponent {
  online$: Observable<boolean>;

  constructor() {
    this.online$ = merge(
      of(navigator.onLine),
      fromEvent(window, 'online').pipe(mapTo(true)),
      fromEvent(window, 'offline').pipe(mapTo(false))
    );
  }
}

Think about what 'offline' means for your use case!

An unplugged ethernet cable and a 3KB/s EDGE connection likely have the same implications for your app although the latter means you're not technically offline!

From a programmer's point-of-view being connected wirelessly with a very poor signal is actually a lot worse than being truely disconnected because it's a lot harder to detect!

The above code returning a false value means your absolutely offline as in disconnected. It returning true doesn't necessarily indicate that there's a practically usable connection.

Sign up to request clarification or add additional context in comments.

8 Comments

always returning true why so ?
No idea. It's totally working for me. Are you sure, you're offline?
i think i am doing something wrong, could you please eleborate your answer bit more
Its possible to do something like that, but cheking an API URL like api.myapi.com/status where the return is Online in case this url is active ?
hey @j2L4e have a look here plnkr.co/edit/Rvjmsg6hDzqOTdwrtP0i?p=preview , i tried your code again but this will work only once than immediate it will toggle the value to TRUE , unable to figure out why ? can you help me out here ?
|
14

At first, j2L4e's answer didn't work for me (testing in Chrome). I tweaked slightly by surrounding my bool in brackets in the ngIf and this ended up working.

<md-icon class="connected" mdTooltip="No Connection" *ngIf="!(isConnected | async)">signal_wifi_off</md-icon>

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/Rx';

@Component({
  selector: 'toolbar',
  templateUrl: './toolbar.component.html',
  styleUrls: ['./toolbar.component.css']
})
export class ToolbarComponent implements OnInit {
  isConnected: Observable<boolean>;

  constructor() {
    this.isConnected = Observable.merge(
      Observable.of(navigator.onLine),
      Observable.fromEvent(window, 'online').map(() => true),
      Observable.fromEvent(window, 'offline').map(() => false));
  }

  ngOnInit() {

  }
}

2 Comments

why import 'rxjs/Rx' library. That's huge and bad practice. moreover, Observable and Subscription have already been imported.
It is always connected! Is connected flag is always true (on latest chrome version), not sure why the state isn't changing!
11

As i have checked navigator is global object like window. You can use in in angular2 and it worked fine for me.

import {Component} from 'angular2/core';
@Component({
    selector: 'my-app',
    template:`
navigator.onLine
{{onlineFlag}}

`
})
export class AppComponent {
  public onlineFlag =navigator.onLine;
}

8 Comments

Working fine in this example. Please check here.
how can i check here on plunker in offline mode ? (in offline mode if i made some changes then page could't be refreshed so i cant check)
First run the code with internet, then remove internet connection and check the value, now you will see value reflecting.
when firstly i remove the connection value changed to false but immediately then value changed to true again without plug in for internet connectoin, may i know whats the reason for the same ?
working fine for me. I am checking in Chrome latest version. Please check your browser once
|
8

Using Angular 6+ and Rxjs 6+, you can do it in the following way:

import { Observable, fromEvent, merge, of } from 'rxjs';
import { mapTo } from 'rxjs/operators';

online$: Observable<boolean>;

constructor() {
  this.online$ = merge(
    of(navigator.onLine),
    fromEvent(window, 'online').pipe(mapTo(true)),
    fromEvent(window, 'offline').pipe(mapTo(false))
  )
}

Here is a demo (toggle network in dev tools)

5 Comments

Would be better if you provide working example of stackblitz etc, anyways thanks, I'll try this one too :)
that's exactly what @Darth_Evil answered way back
@candidJ not quite, notice the syntax difference and the use of pipe()
@Und3rTow I get your point bro. I mean the logic is similar; just using RxJS 6
It does not change when turning off my internet connection, it doesn't work in stackblitz or my app
2

Safe Approach to listen to network states

Answers given above works well but are not considered safe approach.

1.Browser dependent objects like window should not be referenced directly, always check for platform.

2.Furthermore functionality like Network Connection must be encapsulated into a service.

Below is the ConnectionService which can be subscribed to listen network states. It follows the rxjs 6 style.

Complete Code

import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { Observable, fromEvent, merge, empty } from 'rxjs';
import { isPlatformBrowser } from '@angular/common';
import { mapTo } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ConnectionService {

  private connectionMonitor: Observable<boolean>;

  constructor(@Inject(PLATFORM_ID) platform) {
if (isPlatformBrowser(platform)) {
  const offline$ = fromEvent(window, 'offline').pipe(mapTo(false));
  const online$ = fromEvent(window, 'online').pipe(mapTo(true));
  this.connectionMonitor = merge(
    offline$, online$
  );
} else {
  this.connectionMonitor = empty();
}



 }

  monitor(): Observable<boolean> {
    return this.connectionMonitor;
  }
}

in component, you may listen by subscribing to monitor() or directly into HTML using async pipe.

Comments

2

For Angular 9 - a very simple solution and comfortable using (thanks to this and this solutions):

1) Create new component:

ng g c NoConnection

no-connection.component.ts

import { Component, OnInit } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'
import { HttpClient }    from '@angular/common/http';

@Component({
  selector: 'app-no-connection',
  templateUrl: './no-connection.component.html',
  styleUrls: ['./no-connection.component.css']
})
export class NoConnectionComponent implements OnInit {

  isConnectionAvailable: boolean = navigator.onLine; 

  constructor(private httpClient: HttpClient) { 
      window.addEventListener('online', () => {
        this.isConnectionAvailable = true
    });

    window.addEventListener('offline', () => {
        this.isConnectionAvailable = false
    });
  }

  ngOnInit(): void {
  }

}

no-connection.component.html (customise page as you want)

<div>

    <p style.color = "{{ isConnectionAvailable  ? 'green' : 'red'}}"> {{ isConnectionAvailable  ? 'Online' : 'Offline'}} </p>  

    <!-- https://stackoverflow.com/questions/13350663/greyed-out-waiting-page-in-javascript#answer-13350908 -->
    <div id="blackout" class="noselect" style.display = "{{isConnectionAvailable ? 'none' : 'block'}}">
        <br><br><br><br><br>
        <p>No Internet connection!</p>
        <br>
    </div>

</div>

no-connection.component.css

#blackout {
    width:100%;
    height:100%; /* make sure you have set parents to a height of 100% too*/
    position: absolute;
    left:0; top:0;
    z-index:10; /*just to make sure its on top*/

    opacity: 0.5; 
    background-color:#333; 
    text-align: center;

    font-size:25px; 
    color: white;
}

.noselect {
  -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
     -khtml-user-select: none; /* Konqueror HTML */
       -moz-user-select: none; /* Old versions of Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
            user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome, Opera and Firefox */                               
}

2) Use it anywhere you want - in my case the best place - is a root component:

app.component.html

<div>

    <app-no-connection></app-no-connection>

    <app-main></app-main>

</div> 

1 Comment

not working on Windows OS
0

Go with this simple Hack.

Working in angular 5 or later

 constructor(){
    setInterval(()=>{
       if(navigator.onLine){
         //here if it is online
       }else{
        //here if it is offline
       }
    }, 100)
 }

write this in constructor of app.component.ts or your app bootstrap No need of any external library ..

1 Comment

there are already many answers with same content, what's new in this?
0
import { Injectable } from '@angular/core';
import {
    HttpRequest,
    HttpHandler,
    HttpEvent,
    HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class InternetInterceptor implements HttpInterceptor {
    constructor() { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // check to see if there's internet
        if (!window.navigator.onLine) {
            // if there is no internet, throw a HttpErrorResponse error
            // since an error is thrown, the function will terminate here
            return Observable.throw(new HttpErrorResponse({ error: 'Internet is required.' }));

        } else {
            // else return the normal request
            return next.handle(request);
        }
    }
}

1 Comment

Please always describe what you are doing in your answer. It should be updated or removed. Read How to answer before you provide more answers ^^
-3

Use this.

Without any external library.

public isOnline: boolean = navigator.onLine;

ngOnInit() { 
    console.log(this.isOnline); 
}

1 Comment

that's exactly what @sudheerKb had mentioned.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.