54

This is how I would check internet connection in vanilla javascript:

setInterval(function(){
    if(navigator.onLine){
        $("body").html("Connected.");
    }else{
        $("body").html("Not connected.");
    }
},1000);

I have angular controllers and modules in my project. Where should I put the code above? It should be executed in global context and not be assigned to a certain controller. Are there some kind of global controllers maybe?

Charlie
  • 22,886
  • 11
  • 59
  • 90
DarkLeafyGreen
  • 69,338
  • 131
  • 383
  • 601

4 Answers4

153

First of all, I advise you to listen to online/offline events.

You can do it this way in AnguarJS:

var app = module('yourApp', []);

app.run(function($window, $rootScope) {
      $rootScope.online = navigator.onLine;
      $window.addEventListener("offline", function() {
        $rootScope.$apply(function() {
          $rootScope.online = false;
        });
      }, false);

      $window.addEventListener("online", function() {
        $rootScope.$apply(function() {
          $rootScope.online = true;
        });
      }, false);
});

NOTE: I am wrapping changing of root scope's variable in $apply method to notify Angular that something was changed.

After that you can:

In controlller:

$scope.$watch('online', function(newStatus) { ... });

In HTML markup:

 <div ng-show="online">You're online</div>
 <div ng-hide="online">You're offline</div>

Here is a working Plunker: http://plnkr.co/edit/Q3LkiI7Cj4RWBNRLEJUA?p=preview

Other solution could be to broadcast online/offline event. But in this case you need to initialize current status upon loading and then subscribe to event.

ebarrenechea
  • 3,775
  • 1
  • 31
  • 37
Valentyn Shybanov
  • 19,331
  • 7
  • 66
  • 59
19

It's definitely not as nice, but you could just try an AJAX request to your web server; it'll either succeed or time out.

Also, the HubSpot/offline project looks really good.

Jon Onstott
  • 13,499
  • 16
  • 80
  • 133
  • 1
    !+ but, Lol: that's what I am trying to replace. I had a service which is responsible for attempting to reconnect. Anyone who tries an `$http.get` and gets 404 can invoke the service which would 1) broadcast that there was no internet (so that no one else would try to connect), 2) regularly attempt to connect to my server and, 3) when successful, stop the connection attempts and broadcast that the app is now online again. However, that seemed very klunky and this solution seemed elegant - except for FF :-( I cannot be reinventing the wheel here. How do others do it? – Mawg says reinstate Monica May 24 '14 at 00:39
  • Oops, see my comment to the the related question http://stackoverflow.com/questions/15574580/how-can-i-detect-with-angularjs-if-the-app-is-offline "I didn't D/L it, I just opened up their simulator. rather than using their checkbox to pretend, I actually pulled my Ethernet cable. In Chrome & MS IE, I go the "you are offline" alert. FF did not show it. See also stackoverflow.com/questions/16242389/… which indicates that FF seems to be non-standard" – Mawg says reinstate Monica May 24 '14 at 12:02
1

Your options:

  • addEventListener on the window, document, or document.body.

  • setting the .ononline or .onoffline properties on document or
    document.body to a JavaScript Function object.

  • specifying ononline="..." or onoffline="..." attributes on the tag in the HTML markup

I will demonstrate the easiest.

In you controller

document.body.onoffline = function() {
   alert('You are offline now');
   $scope.connection = 'offline' 
}

document.body.ononline = function() {
   alert('You are online again');
   $scope.connection = 'online' 
}

Check $scope.connection variable before you try to send requests around.

Charlie
  • 22,886
  • 11
  • 59
  • 90
0

For Angular 2+ you can use ng-speed-test:

  1. Just install:
npm install ng-speed-test --save
  1. Inject into your module:
import { SpeedTestModule } from 'ng-speed-test';

@NgModule({
   ...
   imports: [
       SpeedTestModule,
       ...
   ],
   ...
})
export class AppModule {}
  1. Use service to get speed:
import {SpeedTestService} from 'ng-speed-test';

@Injectable()
export class TechCheckService {
  constructor(
    private speedTestService:SpeedTestService
  ) {
    this.speedTestService.getMbps().subscribe(
      (speed) => {
        console.log('Your speed is ' + speed);
      }
    );
  }
}
Jeremy
  • 3,620
  • 9
  • 43
  • 75