Last active
August 29, 2015 14:13
-
-
Save andrewluetgers/9bf09e447993e7786ce5 to your computer and use it in GitHub Desktop.
DynaCache: Speed up angular $http requests with Localforage response cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module("dynacache", []) | |
.service("dynacache", function($http) { | |
// drop in replacement for $http | |
// currently supports "get", "post", "put", "jsonp" methods | |
// caches response body in localforage (http://mozilla.github.io/localForage/) | |
// subsequent requests immediately serve up local data | |
// whilst fetching new data from the server | |
// once ajax returns, new data replaces old by firing success handler once again | |
// expects lodash _ global to be present | |
function config() { | |
localforage.config({ | |
name : 'clario', | |
version : 1.0, | |
storeName : 'cache_' + clairoUser.id | |
}); | |
} | |
config(); | |
function clear(fn) { | |
localforage.config(); | |
localforage.clear(fn); | |
} | |
function keys(fn) { | |
localforage.config(); | |
localforage.keys(fn); | |
} | |
function _idFromConfig(config) { | |
return (config.method || "get").toLowerCase() + ":" + config.url + "?" + (decodeURIComponent($.param(config.params)) || "" ); | |
} | |
var _$dcMethods = { | |
success: function (fn) { | |
var that = this; | |
var pending = ""; | |
this.endSuccess = function () { | |
console.log("success", that); | |
var hit = that.hit; | |
if (that.req) { | |
console.log("with req"); | |
// fetched from server | |
var id = _idFromConfig(that.config); | |
pending = id; | |
that.req.success(function (data, status, headers, config) { | |
// save it locally | |
console.log("saving", id); | |
localforage.setItem(id, { | |
data: data, | |
status: status | |
}, function (err, val) { | |
if (err) { | |
console.log(err); | |
} | |
console.log("saved", id, { | |
data: data, | |
status: status | |
}); | |
if (id == pending) { | |
$rootScope.$apply(function () { | |
fn(data, status, headers, config); | |
}); | |
} | |
}); | |
}); | |
} | |
if (hit) { | |
// pull value from the cache | |
console.log("with hit", _idFromConfig(that.config), hit.data); | |
$rootScope.$apply(function() { | |
fn(hit.data, hit.status, hit.headers, hit.config); | |
}); | |
} | |
}; | |
return this; | |
}, | |
error: function (fn) { | |
var that = this; | |
this.endError = function () { | |
console.log("error", that); | |
if (that.req) { | |
// fetched from server | |
that.req.error(function (data, status, headers, config) { | |
$rootScope.$apply(function () { | |
fn(data, status, headers, config); | |
}); | |
}); | |
} | |
}; | |
return this; | |
} | |
}; | |
function _$dc(config, fetchFn) { | |
var ret = _.extend({ | |
req: null, | |
hit: null, | |
config: config | |
}, _$dcMethods); | |
localforage.getItem(_idFromConfig(config), function(err, val) { | |
ret.req = fetchFn(config); | |
ret.hit = val || false; | |
console.log("got item", _idFromConfig(config), err, val); | |
if (ret.endError) { ret.endError(); } | |
if (ret.endSuccess) { ret.endSuccess(); } | |
}); | |
console.log("ret", _idFromConfig(config), ret); | |
return ret; | |
} | |
// support $http() and $http.method() | |
var methods = ["get", "post", "put", "jsonp"]; | |
function dynaCache(config) { | |
return _$dc(config, $http); | |
} | |
dynaCache.success = _$dcMethods.success; | |
dynaCache.error = _$dcMethods.error; | |
dynaCache.idFromConfig = _idFromConfig; | |
dynaCache.keys = keys; | |
dynaCache.clear = clear; | |
_.each(methods, function(method) { | |
dynaCache[method] = function(url, opts) { | |
var config = _.create(opts || {}, {url: url, method: method}); | |
return _$dc(config, $http); | |
}; | |
}); | |
return dynaCache; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment