PhoneGap Online/Offline Tip (2)

This post is more than 2 years old.

A while ago I posted an article discussing how to handle offline and online events in Cordova/PhoneGap (PhoneGap Offline/Online Tip). While working on my book I came across some differences to this behavior that I wanted to document.

As a reminder, the idea is simple. Your PhoneGap/Cordova app should be network aware if it makes any use of remote resources. While the Network Information plugin isn't perfect (and I'll be showing an example of that in a second), there really is no excuse to not add some type of support for this in your application. Having an application that just silently fails is unprofessional - especially considering how easy it is to fix.

Read the earlier entry first - I'll wait.

Now that you've seen an example, there are a few changes you should be aware of.

At the time I wrote the entry, I recommended putting the event listeners in the document ready block if you were using jQuery. Now the recommendation (and this is documented) is to place them in the deviceready listener.

The good news is that the handlers still works as my other blog entry says. They will fire automatically on application startup. The bad news though is that your code needs to be a bit more intelligent about any warnings it may use. What do I mean? My sample code alerted the user when they went offline and online. It makes sense to warn the user immediately if the application starts up offline. It does not make sense to do the same if the application is online. So you need a work around for that. The good news is that the workaround also meshes nicely with a bug.

Cordova issues 7787 describes a bug where in Android, the event listeners may fire multiple times. What that means is that when you test putting your device offline, the event may fire twice or more. If you are using an alert, then that's a problem.

To get around this I used a simple hack. It is harmless on iOS and actually addresses the "starting up online" issue as well. Consider this pseudo-code:


document.addEventListener("deviceready", init, false);
var lastStatus = "";

function init() {

  //listen for changes
  document.addEventListener("offline", disableForm, false);
  document.addEventListener("online", enableForm, false);

}

// stuff

function disableForm() {
  $("#searchButton").attr("disabled", "disabled");
  if(lastStatus != 'disconnected') {
    lastStatus = 'disconnected';
    navigator.notification.alert(
      "Search is disabled while you are offline.", 
      null, 
      "Offline!");
  }
}

function enableForm() {
  $("#searchButton").removeAttr("disabled");
  if(lastStatus != 'connected' && lastStatus != '') {
    lastStatus = 'connected';
    navigator.notification.alert(
      "Search is now enabled.", 
      null, 
      "Online!");
  }
}

Basically, I set a global variable to see if I've switched from one state to another. That handles the Android issue and like I said is harmless on iOS. Notice the enableForm method called in online. This will fire if the application starts online, but we add a check (lastStatus != '') that handles the good startup case and suppresses the alert. (The line removing disabled is harmless too.)

Anyway, I hope this helps!

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by sam1rm posted on 1/21/2015 at 5:32 AM

This is really helpful! Seriously saved my butt.

Comment 2 by Adam posted on 4/12/2015 at 7:03 PM

It was like few minutes to implement this in my project. Great! Thank you!

Comment 3 by Hevelson Rosario posted on 11/27/2015 at 7:38 PM

I have a problem, in my Cordova app the listener "online/offline" doesn't work.

Comment 4 (In reply to #3) by Raymond Camden posted on 11/27/2015 at 8:30 PM

What device are you testing with?

Comment 5 (In reply to #4) by Hevelson Rosario posted on 11/28/2015 at 12:04 PM

many versions of Android, but none worked

Comment 6 (In reply to #5) by Raymond Camden posted on 11/28/2015 at 4:22 PM

When you remote debug, do you see an error? Did you use *exactly* my code?

Comment 7 (In reply to #6) by Hevelson Rosario posted on 11/28/2015 at 9:13 PM

no errors. I use just the listeners.

document.addEventListener('online', function() {alert('ON LISTENER');});
document.addEventListener('offline', function() {alert('OFF LISTENER');});

Comment 8 (In reply to #7) by Raymond Camden posted on 11/28/2015 at 9:27 PM

Did you add the plugin? Is your code the exact same as mine?

Comment 9 (In reply to #8) by Hevelson Rosario posted on 11/30/2015 at 11:35 AM

No. I didn't know that the listener need the plugin. I add the plugin network and worked fine. Thanks for your help

Comment 10 by dmlcreative posted on 2/3/2016 at 11:00 PM

Do you have a complete working example of this? I can't seem to get it to alert me on app load, only if I start on wifi and then disconnect.

Comment 11 (In reply to #10) by Raymond Camden posted on 2/4/2016 at 2:03 AM

I replied on Twitter, but want to reply here too for folks reading: I have a full example in my Cordova book, available via the 'About Me' link above.

Comment 12 by Dmitry Isakov posted on 2/16/2016 at 12:18 AM

I have the similar problem in my two apps: JQM and Ionic. In many situations this plugin says that the device is offline and never gets online. Only if I manually change the state then it works.

Comment 13 by Taiye posted on 2/17/2016 at 2:18 AM

Brilliant!!! works like a charm. tested on android 4.2.2 and ios9. thumbs up.

Comment 14 by Samuel posted on 6/15/2019 at 2:58 PM

Good Work. Was really having a bad day until i came across this. Thank a lot.

Comment 15 (In reply to #14) by Raymond Camden posted on 6/15/2019 at 3:05 PM

You are welcome!