Skip to content

Instantly share code, notes, and snippets.

@joshbedo
Created May 2, 2014 22:10
Show Gist options
  • Save joshbedo/e1fe2b41b71ccc507bac to your computer and use it in GitHub Desktop.
Save joshbedo/e1fe2b41b71ccc507bac to your computer and use it in GitHub Desktop.
localStorageSync.coffee
#storing collections like surveys, past products and other things
#when possible to reduce network requests and make things more snappy
#overriding sync to use local storage when possible
class Backbone.localStorageSync extends Backbone.Model
@sync = (method, model, options) ->
_.defaults(options || (options = {}), {
add: true
})
@storage = window.localStorage
#creates a key based off the uid:key and checks if it exists
@getKey = (key) ->
uid = gon.current_user.id
pair = "#{uid}:#{key}"
if method is 'read' && @storage
#only override sync if it is a fetch('read') request
#passes in the model route to create a pair with the uid:route
route = model.url()[1..-1]
key = @getKey(route)
now = new Date().getTime()
timestamp = @storage.getItem key + ":timestamp"
refresh = @refreshData || false
maxRefresh = @maxRefresh || 999999
if refresh || !timestamp || (( now - timestamp) > maxRefresh)
#make a network request and store result in local storage
success = options.success
options.success = (resp, status, xhr) =>
console.log "success", resp, status, xhr
if options.add && resp.values
#clone the response
newData = JSON.parse(JSON.stringify(resp))
#append values
prevData = @storage.getItem key
newData.values = prevData.values.concat(resp.values)
#store new data in local storage
@storage.setItem key, newData
else
@storage.setItem key, JSON.stringify(resp)
now = new Date().getTime()
@storage.setItem key + ":timestamp", now
success resp, status, xhr
error = options.error
options.error = (originalModel, resp, options) =>
throw new Error("Error has occured during sync of " + route)
if error then error originalModel, resp, options
#call normal backbone sync
Backbone.sync method, model, options
else
#provide data from local storage instead
data = @storage.getItem key
#simulate a normal async network call
setTimeout =>
#create a JSON response with the 'route' containing the model collection
response = '{ "' + route + '":' + data + '}'
options.success JSON.parse(response), 'success', null
, 0
else
Backbone.sync method, model, options
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment