Skip to content

mnitchie/OfflineDemo2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

#Offline Demo 02

This repository contains a number of demo applications meant to show the capabilities, as well as the limits and challenges, of offline api-driven web applications. Every version has a demo running here.

As with this project, here is a single repository that contains multiple tagged releases, each one with incremental changes to the one before. Jump between tags with git checkout VXX, replacing XX with the desired version number. Install the required dependencies with npm install then run with node app.js. It will also be a good idea to run localStorage.clear() in the JavaScript console when switching among the various. PouchDB is used in the later releases and it places artifacts in LocalStorage that cause the earlier versions to break.

This is not meant to be a comprehensive tutorial. There are many of those on the web already. This is meant to compliment those by providing several working examples in context.

This application is the famous to-do list example. Versions 4 and 7 allow for adding entries into the lists created on the main page.

See this repository for example usage of Application Cache alone.

For versions 2-4, MongoDB must be installed. Once installed, simply run with mongod.

For versions 6 and 7, CouchDB must be installed. Cors must be enabled. The included Futon app can be used to start and stop the service. It is also a good idea to set the bind_address to 0.0.0.0, though this may not be necessary if running on localhost.

##V01 View Demo

An offline-first implementation of a to-do list. After visiting the page for the first time, an internet connection is no longer needed to have full interaction.

In order to uniquely identify lists in offline mode, a random ID is generated for them. This ID is prefixed with LOCAL-.

The fields of a List object need some programatic protections, so a programmer can't overwrite Id or createDate fields, for example. However, these fields need to be accessible to the persistence layer for storage. Getters and setters were written for most fields, and a getPersistable() method exists which returns an Object containing the raw data for that List to be persisted.

##V02 View diffs
View demo

In this version, the to-do list application is able to save lists to the server when online, but still persist to local storage when offline.

Care must be taken to keep track of the state of lists created offline to allow for proper syncing. For instance, when a new list is created or an existing list is modified offline, its isDirty property is set. Likewise, when a List is deleted offline its isDeleted property is set. When connection is re-established with the server after a refresh, Lists with these flags set will be persisted to the server, then the localStorage will be wiped out and re-populated with the fresh data from the server.

Syncing is hard. A few things to note:

  • The local ID set on offline-created Lists is ignored on the server in favor of the id set by the DB.
  • It makes no sense to delete a List from the server that only exists locally. If a user creates a List offline, then deletes that same List before going back online, the deleted flag is not set. Instead, the app checks to see if the List has an ID that is prefixed with LOCAL-. If so, it simply removes it from local storage. (A hacky approach, I admit, but still a case that needs to be handled.)
  • Syncing is done via a series of synchronous ajax calls. That makes me squirm a bit, but keeps the sync operation safe from conflicts or errors. It is important that the state from the server overrides the local state only after the local state has been persisted to the server. Otherwise, local changes may be lost.
  • The cache.manifest file now has a NETWORK entry for the api endpoint serving up the List data. This allows that data to come through when online. When offline, the app loads data from local storage instead.

The browser doesn't immediately recognize when internet connection has been lost. It often takes 3-5 seconds(ish). During that time, it can send ajax requests to the server that will fail. Those errors can be handled by falling back to local storage, knowing that everything will get synced back up later.

For example, if a "POST" to the server fails, for any reason, always fall back to persisting it in local storage.

##V03 View diffs
View demo

The app now detects changes in network status using the online and offline events on the window object (also available on document and document.body). Data will now sync when the user's connection status changes, without requiring a refresh.

##V04 View diffs
View demo

An extra feature is added in this version which completes the to-do list functionality. A list can be selected, and entries can be added to that list.

The code here is getting nastier and nastier. Several reasons:

  1. Managing the syncing of data between online and offline states is not trivial. It is also "problem dependent", so there are few hard-and-fast rules to follow.
  2. I probably should have written this demo with Angular or some other SPA framework. Passing data between two pages like this is messy.
  3. I'm getting a bit lazy.
  4. I'm trying to prove a point. As an app gets more complex the data management becomes more and more difficult. There must be an easier way...

##V05 View Diffs
Compare to V01
View Demo

This is nearly* identical to V01, the offline version of the to-do list app. However, StorageManager.js now relies on PouchDB for local data persistence.

*: It is functionally identical. However, there is zombie code left in that will be used or modified in later versions.

##V06 View diffs
Compare with V03
View Demo

This version is functionally identical to V03, but the use of PouchDB and CouchDB makes data synchronization trivial.

##V07 View diffs
Compare with V04
View Demo

Final version. Functionally identical to V04, again pouch/couch makes it so much simpler to manage data synchronization.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published