A drop-in replacement for Angular's $cacheFactory
, the taggedCacheFactory
factory provides support cache expiration and tagging.
When the cache is full, items that have expired will be prioritized for removal before falling back to removing the least-recently-used item. This helps ensure that often-used cache entries will eventually be removed to prevent from showing stale content indefinitely.
var app = angular.module('MyApp', ['tagged.services.cache-factory']);
app.service('myService', ['taggedCacheFactory', 'mySlowApi', function(taggedCacheFactory, mySlowApi) {
var cache = taggedCacheFactory('myServiceCache', {
capacity: 3
});
// Let's cache an expensive call
this.getThingFromSlowServiceById(id) {
var cacheKey = 'thing-' + id;
var cached = cache.get(cacheKey);
if (cached) {
// Cache hit, return it!
return cached;
}
var promise = mySlowApi.getTheThing(id);
cache.put(cacheKey, promise); // cache the thing with no expiration
return promise;
};
// Let's cache another expensive call but expire the entry after 60 seconds
this.getOtherThingFromSlowServiceById(id) {
var cacheKey = 'other-thing-' + id;
var cached = cache.get(cacheKey);
if (cached) {
// Cache hit, return it!
return cached;
}
var promise = mySlowApi.getTheOtherThing(id);
cache.put(cacheKey, promise, 60000); // cache for 60 seconds
return promise;
};
}]);
Each cache entry may optionally contain multiple tags, allowing you to group related cache entries for swift removal at a later time.
var app = angular.module('MyApp', ['tagged.services.cache-factory']);
app.service('myBlogService', ['taggedCacheFactory', 'mySlowApi', function(taggedCacheFactory, mySlowApi) {
var cache = taggedCacheFactory('myBlogCache', {
capacity: 3
});
this.getPost = function(id) {
var cacheKey = 'blog-post-' + id;
var cached = cache.get(cacheKey);
if (cached) {
// Cache hit, return it!
return cached;
}
var promise = mySlowApi.getBlogPost(id);
// Cache blog post promise and tag it as 'blog-{id}'
cache.put(cacheKey, promise, null, 'blog-' + id);
return promise;
};
this.getComments = function(id) {
var cacheKey = 'blog-comments-' + id;
var cached = cache.get(cacheKey);
if (cached) {
// Cache hit, return it!
return cached;
}
var promise = mySlowApi.getBlogComments(id);
// Cache blog comments promise and tag it as 'blog-{id}'
cache.put(cacheKey, promise, null, 'blog-' + id);
return promise;
};
this.deletePost = function(id) {
// Make API call to delete the post
return mySlowApi.deleteBlogPost(id)
.then(function(result) {
// Delete all cache entries for this post with just one call!
// In this example, the cache for the post as well as the comments will be removed.
cache.removeMatchingTag('blog-' + id);
})
.catch(function(error) {
// Oops, something went wrong!
});
};
});
To get started, add tagged-cache-factory-min.js
to your webpage:
<script type="text/javascript" src="path/to/tagged-cache-factory-min.js"></script>
And add the module tagged.services.cache-factory
to your app's dependencies:
var app = angular.module('MyApp', ['tagged.services.cache-factory']);
Then simply inject taggedCacheFactory
whenever you need to create a new cache.
- AngularJS 1.1.5 - 1.3.x
- RequireJS (Optional)
This service can be loaded as an AMD module if you're using RequireJS. There are a few requirements:
- You must add paths to
angular
in your RequireJS config. - You must shim
angular
to exportangular
At minimum, your requirejs config must include this:
requirejs.config({
paths: {
'angular': 'path/to/angular'
},
shim: {
'angular': {
'exports': 'angular'
}
}
});
Once configured, you can require()
the original source file src/tagged-cache-factory
in your app:
define(['angular', 'path/to/src/tagged-cache-factory'], function(angular) {
var app = angular.module('MyApp', ['tagged.services.cache-factory']);
// ...
});
Requirements
- nodejs 1.10.x
- npm 1.2.32
To set up the development environment, run these commands once:
# Global dependencies
$ npm install --global grunt-cli bower
# Local node dependencies (karma, etc.)
$ npm install
# 3rd-party libraries (Angular)
$ bower install
Running Tests Once the development environment has been set up, tests can be run in a number of ways:
# Run all tests once
$ grunt test
# Run tests in development mode (enables file watcher to automatically rerun tests)
$ grunt dev
Building Production Files
# Build production files in `./`
$ grunt build
Contributions welcome! All we ask is that pull requests include unit tests. Thanks!
Copyright 2015 Tagged, Inc.