DataSync PhoneGap/Web applications using LocalStorage
Conditions were like below:
- Store data in queue locally in LocalStorage
- Sync data with server if online
- when application comes online it should start syncing the data again if any
- upon successful sync remove from queue else try again
- synching one item at a time
Lets start understanding the solution.
1. Backbone Modelvar QueueModel = Backbone.Model.extend({ defaults:{ 'url': null, 'method': null //http method like GET, PUT, POST etc. } });This model is nothing but representation of ajax settings that can be found here.
2. Backbone Collection used as a Queue which is using Backbone.LocalStorage plugin. You should use singleton pattern for following backbone class.
var SyncQueue = Backbone.Collection.extend({ model: QueueModel, currentModel: null, timeOutVar: null, localStorage: new Backbone.LocalStorage(QUEUE_NAME), initialize: function() { setSelf(this); }, setSyncTimer: function(milliSeconds) { milliSeconds = typeof milliSeconds !== 'undefined' ? milliSeconds : 5000; if(self.timeOutVar) { clearTimeout(self.timeOutVar); } setTimeout(self.startSync, milliSeconds); }, //add model into queue enqueue: function (model) { self.localStorage.create(model); self.setSyncTimer(1000); }, //when syncing is done syncSuccess: function () { self.localStorage.destroy(self.currentModel); self.currentModel = null; self.setSyncTimer(1000); }, //when error occurred while syncing syncError: function () { self.currentModel = null; setTimeout(self.startSync, 1000); }, //sync init method startSync: function () { console.log('startSync '+ 'models length: ' + self.models.length); self.localStorage = new Backbone.LocalStorage(QUEUE_NAME); self.fetch(); if (self.models.length > 0 && self.currentModel === null) { self.currentModel = self.models[0]; self.send(); } }, send: function() { var ajaxJSON = self.currentModel.toJSON(); $.ajax(ajaxJSON) .done(function(){ self.syncSuccess(); }) .fail(function(){ self.syncError(); }); } });
Understanding above Backbone Collection
model: QueueModel = Set Backbone collection modelcurrentModel: null = currentModel being synced
timeOutVar: null = holds reference to timeout id
enqueue: function (model) { self.localStorage.create(model); self.setSyncTimer(1000); },Above function will add ajax settings model in the queue. As I said earlier this is essentially jquery ajax settings like url, method, contentType, dataType etc.
syncSuccess: function () { self.localStorage.destroy(self.currentModel); self.currentModel = null; self.setSyncTimer(1000); },Success callback after ajax is successful. It will remove currentModel from queue and will start synching method again.
syncError: function () { self.currentModel = null; setTimeout(self.startSync, 1000); },Error callback when ajax is unsuccessful. It will again try to sync the same model again.
startSync: function () { console.log('startSync '+ 'models length: ' + self.models.length); self.localStorage = new Backbone.LocalStorage(QUEUE_NAME); self.fetch(); if (self.models.length > 0 && self.currentModel === null) { self.currentModel = self.models[0]; self.send(); } }Above is the function which will fetch collection from localStorage and it will try to sync first model from queue.
send: function() { var ajaxJSON = self.currentModel.toJSON(); $.ajax(ajaxJSON) .done(function(){ self.syncSuccess(); }) .fail(function(){ self.syncError(); }); }This function will execute ajax on currentModel and will call respective callback function.
I am using above code as is in one of my application which is currently in beta mode. Improvement to above synching code can be done. If you have any suggestions please let me know.
You can find demo of above code at http://jsfiddle.net/bharatpatil/EeNH2/3/
Comments
Post a Comment