jmdobry / angular-cache

angular-cache is a very useful replacement for the Angular 1 $cacheFactory.
http://jmdobry.github.io/angular-cache
MIT License
1.39k stars 156 forks source link

angular-cache not working with $http #143

Closed cboden closed 9 years ago

cboden commented 9 years ago

I'm following the documentation for using angular-cache with $http from the website and I'm getting some very unexpected behaviour:

.factory('myModel', function($http, DSCacheFactory) {
    DSCacheFactory('myModelCache'); // tried various options, didn't help

    return function() {
        return $http.get('/my/endpoint', {cache: DSCacheFactory.get('myModelCache')}).then(function(result) {
            return result.data.data;
        });
    }
})

.run(function(myModel) {
    myModel().then(function(data) {
        console.log('1: ', data);

        myModel().then(function(again) {
            console.log('3: ', again);
        });
    });

    myModel().then(function(data) {
        console.log('2: ', data);
    });
})

Only 1 and 3 are logged. Using run in this way makes for a bit of a convoluted demo, but I noticed in various places that used my model didn't have the data and this was a way to replicate the behaviour. Only one HTTP request is ever made (which is good and expected) but the data isn't always being retrieved. If I change the cache option in $http.get from DSCacheFactory to just true Angular handles the caching as expected.

I'm using Angular 1.2.23 with angular-cache 3.2.1

jmdobry commented 9 years ago

I just barely added a fix that allows angular-cache to work with $http promises in addition to other promises inserted manually by developers. By default, angular-cache tries to "put" the resolved value of the promise into the cache when the promise resolves. This doesn't play nice with $http because $http is also trying to manage the promise lifecycle.

If you change your example from DSCacheFactory('myModelCache'); to:

DSCacheFactory('myModelCache', {
  storeOnResolve: false,
  storeOnReject: false
});

then it will work with $http just fine. I haven't had a chance to update the documentation yet.

See #135 for further reference.

cboden commented 9 years ago

Thanks for the quick response and solution.

Shouldn't those options be false by default if angular-cache is a drop in replacement for Angular's cache?

jmdobry commented 9 years ago

Probably