JS API Web Application with Disconnected Editing

1288
4
09-16-2013 01:08 PM
BrianBeck
New Contributor III
Is it currently possible to develop disconnected editing functionality within a JS API web application?  I am developing an editing application using the JS API and ArcGIS Online webmaps and we would like to be able to edit data in a disconnected environment and then sync the data when we reconnect.  Is this possible?
0 Kudos
4 Replies
ReneRubalcava
Frequent Contributor
It's possible, but requires a little bit of elbow grease.
You could basically check for a connection on each save or edit by using navigator.onLine.
If false, you have no connection, and set up something to store the feature in LocalStorage.
If true, push update as normal. You just need to add a notification of some sort letting user know they have data that needs to be synced when they get a connection back. Or you could do it under the hood without them knowing.

You could use that method in conjunction with this sample on storing tiles in LocalStorage and be halfway there.
https://developers.arcgis.com/en/javascript/jssamples/exp_webstorage.html

Combine that with ApplicationCache if you can and be well on your way.

I'm getting good results so far, but I have not hit the LocalStorage limit (maybe 5mb if lucky) (edit, spoke too soon. I was hitting limit, just forgot to check for it. I have a clear cache button now) and unless you are using IE9+ I don't think you can check what space is left, you'll just get an error when you run out, so I'm looking into modifying the Tile Storage slightly to add a date element or a 'viewed" count and eliminate the oldest/leaset used tiles to make room for more.

One thing I have not tried yet is using IndexedDB to store features. Maybe once I get this off the ground first.

I'm hoping to add disconnected editing tutorial into some stuff I am working on.
0 Kudos
KarenRobine
Occasional Contributor II
Hello Rene:
I wonder if you might have any examples showing some of the ideas you discussed? It's been a few months since you left this message. Was the application successful?  Thanks.

Karen




It's possible, but requires a little bit of elbow grease.
You could basically check for a connection on each save or edit by using navigator.onLine.
If false, you have no connection, and set up something to store the feature in LocalStorage.
If true, push update as normal. You just need to add a notification of some sort letting user know they have data that needs to be synced when they get a connection back. Or you could do it under the hood without them knowing.

You could use that method in conjunction with this sample on storing tiles in LocalStorage and be halfway there.
https://developers.arcgis.com/en/javascript/jssamples/exp_webstorage.html

Combine that with ApplicationCache if you can and be well on your way.

I'm getting good results so far, but I have not hit the LocalStorage limit (maybe 5mb if lucky) (edit, spoke too soon. I was hitting limit, just forgot to check for it. I have a clear cache button now) and unless you are using IE9+ I don't think you can check what space is left, you'll just get an error when you run out, so I'm looking into modifying the Tile Storage slightly to add a date element or a 'viewed" count and eliminate the oldest/leaset used tiles to make room for more.

One thing I have not tried yet is using IndexedDB to store features. Maybe once I get this off the ground first.

I'm hoping to add disconnected editing tutorial into some stuff I am working on.
0 Kudos
ReneRubalcava
Frequent Contributor
I have had really good luck so far.

My first recommendation for people is to test out LocalStorage first. If that meets your needs, count yourself lucky.
I don't want to pimp, but I cover this type of disconnected editing in my book in a much simpler method.

In my production application, the field users are only ever concerned with very specific neighborhood level data, so using the TileStorage extension of tiled layers is working ok, but I do clear it every time the app starts, just in case, because you can hit the LocalStorage limit pretty quickly.

Now, if you want to get into IndexedDB for data collection and not pollute your LocalStorage with it, I tested out writing an IndexedDB Store that worked pretty well.
https://gist.github.com/odoe/6911676#file-indexeddbstore-js

At least it worked everywhere except for iOS devices. iOS does not support IndexedDB no matter the browser, not even Chrome. Unless that's changed in the past couple of months, iOS browsers only support LocalStorage and WebSQL. This puts the developer in a silly situation of having to check which type of storage solution is available to use and pick it as necessary. Basically create a service interface that will call the appropriate storage methods for you. Plus, I didn't feel like writing a WebSQL Store.

Again, there is a neat solution for that in the form of PouchDB.
http://pouchdb.com/
It's a great little tool that handles all the heavy lifting of working with backend databases. They don't make it very clear in the documentation that I could see, but it will normally use IndexedDB for storage, but on iOS will use WebSQL without you having to tell it to. I using was an adapter at first and twitter raving about PouchDB when the author told me it was now integrated into PouchDB core, so that was a pleasant surprise.

So now, I use this PouchDB Store in my production app.
https://gist.github.com/odoe/6911676#file-pouchdbstore-js

It works great saving and pulling my data out, it's all just a matter of converting the graphics to json strings and parsing them back to json and pushing the adds/updates/deletes.

I'm still waiting on feedback from field testing on how the users prefer to so sync the data. Either by manually pushing a sync button or behind the scenes as soon as a connection becomes available.

The other challenge is determining when you are offline. Here is a great SO answer discussing What does it mean to be "online"?

I have not tackled the Application Cache yet, but my basic plan is to run through the app with a few tasks, make a list of all the JS files used via CDN as well my own for the app and add them to the cache list, which would be pretty long. I'm not even sure I'll go this route as these types of web apps need some sort of connection mainly for base data.

I suppose if your data set is not that large, you could store it locally and load it as a FeatureCollection to a FeatureLayer, maybe save some Tiles in local storage and combinged with the Application Cache have a fully offline capable map. It would probably need to be really simple though. The native SDKs have the advantage of access to new tools for offline, which are looking very attractive for field apps.
https://developers.arcgis.com/en/android/whats-new.html#beta
https://developers.arcgis.com/en/ios/info/whats-new.htm#ESRI_SECTION2_71BFA93C1AE64D58BBFAB139D17320...

My long, and apparently drawn out point, is that you can do a lot with disconnected editing with ArcGIS JS apps. Not everything and not without some trial & error, but you can do something.
0 Kudos
KarenRobine
Occasional Contributor II
Excellent answer Rene. And feel free to "pimp". I loved your sample on Angular JS and am using Angular JS extensively for another project I'm working on.  Appreciate it!
0 Kudos