Tested: IE 9+; Edge 13; Chrome 29, 50+; Firefox 46+; Safari 7+; iOS 9.2+; Android 4.4, 5.1.
Easy ETag-based caching for $http
service requests! Increase responsiveness, decrease bandwidth usage.
- Caches ETag headers and sends them back to the server in the
If-None-Match
header. - Caches response data with flexible cache configuration.
- Support for
$cacheFactory
,sessionStorage
, andlocalStorage
caches out-of-the-box. - Easily adaptable for other third-party cache services.
- Compatible with AngularJS 1.2–1.6.
Example Usage:
angular
.module('myApp', [
'http-etag'
])
.config(function (httpEtagProvider) {
httpEtagProvider
.defineCache('persistentCache', {
cacheService: 'localStorage'
})
})
.controller('MyCtrl', function ($http) {
var self = this
$http
.get('/my_data.json', {
etagCache: 'persistentCache'
})
.then(function success (response, itemCache) {
var data = response.data
// Modify the data from the server
data._fullName = data.first_name + ' ' + data.last_name
// Update the cache with the modified data
itemCache.set(data)
// Assign to controller property
self.fullName = data._fullName
}, function error (response) {
if (response.status != 304) alert('Request error')
})
// Synchronous method called if request was previously cached
// status == 'cached'; headers === undefined;
.ifCached(function (response, itemCache) {
self.fullName = data._fullName
})
})
Need more information on how ETags work? Read this.
$ npm install angular-http-etag
Or download from master/release
Include 'http-etag'
in your module's dependencies.
// The node module exports the string 'http-etag'...
angular.module('myApp', [
require('angular-http-etag')
])
// ... otherwise, include the code first then the module name
angular.module('myApp', [
'http-etag'
])
.config(function ('httpEtagProvider') {
httpEtagProvider
.defineCache('persistentCache', {
cacheService: 'localStorage'
})
.defineCache('sessionCache', {
cacheService: 'sessionStorage'
})
.defineCache('memoryCache', {
cacheService: '$cacheFactory',
cacheOptions: {
number: 50 // LRU cache
},
deepCopy: true // $cacheFactory copies by reference by default
})
})
If you so desire, you can define your own caches. The default cache uses $cacheFactory
and is limited to 25 cache items (Least Recently Used algorithm).
Define the caches you'd like to use by using defineCache(cacheId[, config])
, passing a cache ID
followed by the cache configuration. The configuration you pass will extend the
default configuration, which can be set using the setDefaultCacheConfig(config)
method. If you don't pass a config, a new cache will be defined using the default config.
See more in the Service Provider documentation.
Using the default cache with default configuration and an automatically generated cache itemKey based on the request:
$http.get('/data', {
etagCache: true
})
.then(responseHandler)
.ifCached(responseHandler)
function responseHandler (response, itemCache) {
// Differentiating between cached and successful request responses
var isCached = response.status === 'cached'
// itemCache is a cache object bound to the cache item associated with this request.
itemCache.info()
// { id: 'httpEtagCache',
// itemKey: '/data',
// deepCopy: false,
// cacheResponseData: true,
// cacheService: '$cacheFactory',
// cacheOptions: { number: 25 } }
}
Using a defined cache from the previous section and an automatically generated cache itemKey:
$http.get('/data', {
etagCache: 'persistentCache'
})
.then(responseHandler)
.ifCached(responseHandler)
function responseHandler (response, itemCache) {
itemCache.info()
// { id: 'persistentCache',
// itemKey: '/data',
// deepCopy: false,
// cacheResponseData: true,
// cacheService: 'localStorage',
// cacheOptions: { number: 25 } }
}
Using a defined cache and a specified key for the cache item:
$http.get('/data', {
etagCache: {
id: 'persistentCache',
itemKey: 'whatFineKeyYouHave'
}
})
.then(responseHandler)
.ifCached(responseHandler)
function responseHandler (response, itemCache) {
itemCache.info()
// { id: 'persistentCache',
// itemKey: 'whatFineKeyYouHave',
// deepCopy: false,
// cacheResponseData: true,
// cacheService: 'localStorage',
// cacheOptions: { number: 25 } }
}
The etagCache
property also accepts a function that returns on of the values
demonstrated; a boolean
, a string
, or an object
.
See more in the $http Decorator and Service documentation.
Write an issue. Then, possibly, hopefully...
- Fork the repo.
- Make a branch.
- Write the code.
- Write the tests.
- Run tests. (
npm test
) - Open a pull request.