Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
feat(http): set custom default cache in $http.defaults.cache
Browse files Browse the repository at this point in the history
When we need more control over http caching, we may want to provide
a custom cache to be used in all http requests by default.

To skip default cache, set {cache: false} in request configuration.
To use other cache, set {cache: cache} as before.

See #2079
  • Loading branch information
ashtuchkin authored and jbdeboer committed Mar 8, 2013
1 parent 603fe0d commit 99f3b70
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/ng/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ function $HttpProvider() {
* cache, but the cache is not populated yet, only one request to the server will be made and
* the remaining requests will be fulfilled using the response for the first request.
*
* A custom default cache built with $cacheFactory can be provided in $http.defaults.cache.
* To skip it, set configuration property `cache` to `false`.
*
*
* # Response interceptors
*
Expand Down Expand Up @@ -733,8 +736,10 @@ function $HttpProvider() {
promise.then(removePendingReq, removePendingReq);


if (config.cache && config.method == 'GET') {
cache = isObject(config.cache) ? config.cache : defaultCache;
if ((config.cache || defaults.cache) && config.cache !== false && config.method == 'GET') {
cache = isObject(config.cache) ? config.cache
: isObject(defaults.cache) ? defaults.cache
: defaultCache;
}

if (cache) {
Expand Down
71 changes: 71 additions & 0 deletions test/ng/httpSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,77 @@ describe('$http', function() {
expect(callback).toHaveBeenCalledOnce();
})
);

describe('$http.defaults.cache', function () {

it('should be undefined by default', function() {
expect($http.defaults.cache).toBeUndefined()
});

it('should cache requests when no cache given in request config', function() {
$http.defaults.cache = cache;

// First request fills the cache from server response.
$httpBackend.expect('GET', '/url').respond(200, 'content');
$http({method: 'GET', url: '/url'}); // Notice no cache given in config.
$httpBackend.flush();

// Second should be served from cache, without sending request to server.
$http({method: 'get', url: '/url'}).success(callback);
$rootScope.$digest();

expect(callback).toHaveBeenCalledOnce();
expect(callback.mostRecentCall.args[0]).toBe('content');

// Invalidate cache entry.
$http.defaults.cache.remove("/url");

// After cache entry removed, a request should be sent to server.
$httpBackend.expect('GET', '/url').respond(200, 'content');
$http({method: 'GET', url: '/url'});
$httpBackend.flush();
});

it('should have less priority than explicitly given cache', inject(function($cacheFactory) {
var localCache = $cacheFactory('localCache');
$http.defaults.cache = cache;

// Fill local cache.
$httpBackend.expect('GET', '/url').respond(200, 'content-local-cache');
$http({method: 'GET', url: '/url', cache: localCache});
$httpBackend.flush();

// Fill default cache.
$httpBackend.expect('GET', '/url').respond(200, 'content-default-cache');
$http({method: 'GET', url: '/url'});
$httpBackend.flush();

// Serve request from default cache when no local given.
$http({method: 'get', url: '/url'}).success(callback);
$rootScope.$digest();
expect(callback).toHaveBeenCalledOnce();
expect(callback.mostRecentCall.args[0]).toBe('content-default-cache');
callback.reset();

// Serve request from local cache when it is given (but default filled too).
$http({method: 'get', url: '/url', cache: localCache}).success(callback);
$rootScope.$digest();
expect(callback).toHaveBeenCalledOnce();
expect(callback.mostRecentCall.args[0]).toBe('content-local-cache');
}));

it('should be skipped if {cache: false} is passed in request config', function() {
$http.defaults.cache = cache;

$httpBackend.expect('GET', '/url').respond(200, 'content');
$http({method: 'GET', url: '/url'});
$httpBackend.flush();

$httpBackend.expect('GET', '/url').respond();
$http({method: 'GET', url: '/url', cache: false});
$httpBackend.flush();
});
});
});


Expand Down

1 comment on commit 99f3b70

@mgonto
Copy link

@mgonto mgonto commented on 99f3b70 May 7, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition.

However, it was really hard to find this. This should be documented in AngularJS somewhere or somehow. I've had already 2 people asking about it at https://github.com/mgonto/restangular (and also myself) and it's not really promoted.

I think it's one of the greatest features you've added recently.

Thanks again!

Please sign in to comment.