angular-cache is a very useful replacement for the Angular 1 $cacheFactory.
angular-cache is a very useful replacement for the Angular 1 $cacheFactory.
A very useful replacement for Angular's $cacheFactory.
versions of angular-cache below 4.0.0 have been deprecated, see the breaking changes in 4.0.0
bower install --save angular-cache or npm install --save angular-cache.
…| Feature | $cacheFactory | angular-cache |
|---|---|---|
| core implementation usable outside of Angular | no | yes |
| key/value store | yes | yes |
| in-memory support | yes | yes |
| localStorage support | no | yes |
| sessionStorage support | no | yes |
| custom storage support | no | yes |
| can set maximum capacity | yes | yes |
| LRU support | yes | yes |
| support for time-based expiration of items | no | yes |
| remove all expired items | n/a | yes |
| "touch" an item | n/a | yes |
| execute callback when an item expires | n/a | yes |
| get info about cache | yes | yes |
| get info about single item | no | yes |
| get item by key | yes | yes |
| remove item by key | yes | yes |
| remove all items | yes | yes |
| get keys of all caches | no | yes |
| clear all caches | no | yes |
| disable/enable a cache | no | yes |
| "touch" all items in all caches | n/a | yes |
| remove expired items from all caches | n/a | yes |
| get all keys in a cache | no | yes |
| clear a cache on a given interval | no | yes |
First, inject CacheFactory then create a cache. Let's go:
app.service('myService', function (CacheFactory) {
var profileCache;
// Check to make sure the cache doesn't already exist
if (!CacheFactory.get('profileCache')) {
profileCache = CacheFactory('profileCache');
}
});Let's add some items to the cache:
profileCache.put('/profiles/34', {
name: 'John',
skills: ['programming', 'piano']
});
profileCache.put('/profiles/22', {
name: 'Sally',
skills: ['marketing', 'climbing', 'painting']
});Right now, these items will stay in the cache until a page refresh.
Let's have items which are added to profileCache expire after an hour:
profileCache = CacheFactory('profileCache', {
maxAge: 60 * 60 * 1000 // 1 hour
});Perfect. Say we also want the items removed from the cache when they expire:
profileCache = CacheFactory('profileCache', {
maxAge: 60 * 60 * 1000, // 1 hour
deleteOnExpire: 'aggressive'
});Let's say that when the items do expire, we want to refresh them with new values:
profileCache = CacheFactory('profileCache', {
maxAge: 60 * 60 * 1000, // 1 hour
deleteOnExpire: 'aggressive',
onExpire: function (key, value) {
$http.get(key).success(function (data) {
profileCache.put(key, data);
});
}
});Or say we want all of our caches to use that configuration as their default:
angular.module('app', ['angular-cache']).config(function (CacheFactoryProvider) {
angular.extend(CacheFactoryProvider.defaults, {
maxAge: 3600000,
deleteOnExpire: 'aggressive',
onExpire: function (key, value) {
var _this = this; // "this" is the cache in which the item expired
angular.injector(['ng']).get('$http').get(key).success(function (data) {
_this.put(key, data);
});
}
});
});We can retrieve items from a cache like so:
var profile = profileCache.get('/profiles/34');
profile.name; // 'John'And get information about items in the cache:
var info = profileCache.info('/profiles/34');
info.isExpired; // false
// etc.and information about the cache itself:
var info = profileCache.info();
info.size; // 2
info.maxAge; // 3600000
info.deleteOnExpire; // 'aggressive'
// etc.Items are easily removed, and we can destroy our cache when we're done with it:
profileCache.remove('/profiles/34');
profileCache.get('/profiles/34'); // undefined
profileCache.destroy();
CacheFactory.get('profileCache'); // undefinedThese options apply to:
CacheFactory(cacheId[, options)CacheFactory.createCache(cacheId[, options])Cache#setOptions(options[, strict])Cache#setMaxAge(maxAge), Cache#setOnExpire(onExpire), etc.cacheFlushIntervalIf set, remove all items from a cache on an interval after the given number of milliseconds. Default: null.
capacityMaximum number of items a cache can hold. Adding more items than the capacity will cause the cache to operate like an LRU cache, removing the least recently used items to stay under capacity. Default: Number.MAX_VALUE.
deleteOnExpireDetermines the behavior of a cache when an item expires. Default: none.
Possible values:
none - Cache will do nothing when an item expires.passive - Cache will do nothing when an item expires. Expired items will remain in the cache until requested, at which point they are removed, and undefined is returned.aggressive - Cache will remove expired items as soon as they are discovered.disabledDetermines whether a cache is disabled. Default: false.
onExpireA callback function to be executed whenever an expired item is removed from a cache when the cache is in passive or aggressive mode. Will be passed the key and value of the expired item.
Will be passed a third done argument if the cache is in passive mode. This allows you to synchronously access the key and value of the expired item when you make the Cache#get(key[, options]) call that is the reason the expired item is being removed in the first place. Default: null.
maxAgeThe number of milliseconds until a newly inserted item expires. Default: Number.MAX_VALUE.
recycleFreqDetermines how often a cache will scan for expired items when in aggressive mode. Default: 1000 (milliseconds).
storageImplProvide a custom storage medium, e.g. a polyfill for localStorage. Default: null.
Must implement:
setItem - Same API as localStorage.setItem(key, value)getItem - Same API as localStorage.getItem(key)removeItem - Same API as localStorage.removeItem(key)storageModeDetermines the storage medium used by a cache. Default: memory.
Possible values:
memory - Cache will hold data in memory. Data is cleared when the page is refreshed.localStorage - Cache will hold data in localStorage if available. Data is not cleared when the page is refreshed.sessionStorage - Cache will hold data in sessionStorage if available. Data is not cleared when the page is refreshed.storagePrefixDetermines the namespace of a cache when storageMode is set to localStorage or sessionStorage. Make it a shorter string to save space. Default: angular-cache.caches..
storeOnRejectIf inserting a promise into a cache, also insert the rejection value if the promise rejects. Default: false.
If inserting a promise into a cache, also insert the resolved value if the promise resolves. Default: false.
Note: The downside of letting $http handle caching for you is that it caches the responses (in string form) to your requests–not the JavaScript Object parsed from the response body. This means you can't interact with the data in the cache used by $http. See below for how to handle the caching yourself, which gives you more control and the ability to interact with the cache (use it as a data store).
Configure $http to use a cache created by CacheFactory by default:
app.run(function ($http, CacheFactory) {
$http.defaults.cache = CacheFactory('defaultCache', {
maxAge: 15 * 60 * 1000, // Items added to this cache expire after 15 minutes
cacheFlushInterval: 60 * 60 * 1000, // This cache will clear itself every hour
deleteOnExpire: 'aggressive' // Items will be deleted from this cache when they expire
});
});app.service('MyService', function ($http, $q) {
return {
getDataById: function (id) {
var deferred = $q.defer();
var start = new Date().getTime();
$http.get('api/data/' + id, {
cache: true
}).success(function (data) {
console.log('time taken for request: ' + (new Date().getTime() - start) + 'ms');
deferred.resolve(data);
});
return deferred.promise;
}
};
});app.controller('myCtrl', function (MyService) {
MyService.getDataById(1).then(function (data) {
// e.g. "time taken for request: 2375ms"
// Data returned by this next call is already cached.
return MyService.getDataById(1).then(function (data) {
// e.g. "time taken for request: 1ms"
});
});
});Tell $http to use a cache created by CacheFactory for a specific request:
…app.controller('myCtrl', function (MyService) {
MyService.getDataById(1).then(function (data) {
// e.g. "time taken for request: 2375ms"
// Data returned by this next call is already cached.
return MyService.getDataById(1).then(function (data) {
// e.g. "time taken for request: 1ms"
});
});
});Do your own caching while using the $http service:
…app.controller('myCtrl', function (MyService) {
MyService.getDataById(1).then(function (data) {
// e.g. "time taken for request: 2375ms"
// Data returned by this next call is already cached.
return MyService.getDataById(1).then(function (data) {
// e.g. "time taken for request: 1ms"
});
});
});…Using angular-cache in browsers that DON'T support localStorage:
Option 1 - Do nothing (the cache will just store data in memory)
Option 2 - Create/use a polyfill that provides the global localStorage and sessionStorage objects. angular-cache will attempt to use these if it finds them.
Option 3 - Tell angular-cache exactly which polyfill to use (also useful if you just want to use your own implementation/wrapper for localStorage):
…Documentation on the interface that must be implemented by any storageImpl polyfill used by angular-cache can be found on the W3C Recommendation page for webstorage. The interface itself looks like:
interface Storage {
readonly attribute unsigned long length;
DOMString? key(unsigned long index);
getter DOMString getItem(DOMString key);
setter creator void setItem(DOMString key, DOMString value);
deleter void removeItem(DOMString key);
void clear();
};angular-cache cares only about these three methods:
setItemgetItemremoveItemOne developer suggested using store.js–a wrapper and polyfill for localStorage. However, store.js has its own API that doesn't match that of the webstorage spec, so if you want to use store.js or any other 3rd-party polyfill then you'll need to create a wrapper for it if it doesn't have the same API as localStorage . For example:
var storeJsToStandard {
getItem: store.get,
setItem: store.set,
removeItem: store.remove
};
CacheFactory('myNewCache', {
storageMode: 'localStorage',
storageImpl: storeJsToStandard
});CacheFactory(cacheId[, options]) & CacheFactory.createCache(cacheId[, options])Create a cache. Cache must not already exist. cacheId must be a string. options is an optional arg
No open issues yet, or sync has not completed.