Offline Web Apps – Part 2: navigator.onLine

In Part 1 of this two part blog post, I covered a few of the basic fundamentals of offline web apps. Specifically, how to use a cache manifest to cache application resources offline in the browser. In part 2 we will dive into the how to ensure your application is intelligent enough to handle offline scenarios using navigator.onLine.

Meet navigator.onLine

Caching application resources is a nice feature provides end users with the ability to have client side interactions with your application while they are offline. But what happens when your application needs to communicate with a server? To do so, you need to write javascript code that will take into account how to handle user driven events based on online/offline status. With the HTML5, there is a helpful state property of the Navigator object onLine along with two events that get fired (ononline/onoffline) when the connection status changes.

A Real-world Example

Let’s say for example you have a client side application where users enter large amounts of text content that gets saved to a server somewhere. In order to prevent users from losing work by an unintended browser close, you want to occasionally “autosave” their data every 30 seconds. This code might look something like this:

window.addEventListener('load', function () {
    var saveInterval = setInterval(function () {
        // Function call (XHR etc) to save data goes here
        ...        
    }, 30000) // Call this function every 30 seconds
});

Unfortunately, as straightforward as this implementation is, it leaves some pretty big gaps:

  • The function call to save data will repeat every 30 seconds regardless of success/failure
  • Users have no idea whether or not their data is indeed being saved to the server

Let’s fix this by using navigator.onLine and the ononline/onoffline events:

window.addEventListener('load', function () {           

    function updateOnlineStatus() {
        var condition = navigator.onLine ? "online" : "offline",
            saveInterval = null;
        if (condition === "online") {
            // Make update to UI here to let user know they are online and autosave is available
            ...
            ...
            saveInterval = setInterval(function () {
                    // Function call (XHR etc) to save data goes here
                       ...
                       ...
                    }, 30000)
                }
                else {
                    // Make update to UI here to let user know they are offline and are not autosaving
                    ...
                    ...
                    // Stop the interval from repeating until connectivty is resolved
                    clearInterval(saveInterval); 
                }
            }

        // Setup event listeners for when online/offline status changes
        window.addEventListener('online', updateOnlineStatus);
        window.addEventListener('offline', updateOnlineStatus);

        // Make initialization call to updateOnlineStatus
        pdateOnlineStatus();
});

With the code above, we have pretty solid coverage for when (and when NOT) to save changes based on connection status. As you can imagine though, the more complex an application is, the more complex these scenarios might become.

Additional Considerations and Resources

Like any other that gets executed in the browser, there are some subtleties to watch out for when it comes to cross browser compatability. At this time of this writing Firefox ignores actual network connectivity and instead triggers on the browser’s “Work Offline” mode. In addition, some browser/operating system combinations may not be intelligent enough to determine the difference between a true network connection and a local network adapter (virtual) showing an online status. For more information, please take a look at the following links: