Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalidating all $http caches in Angular

I have an Angular application with a number of services based on Angular's built-in $resource service. Many of these use the cacheFactory to create their own independent caches. However, I want to blow all of these away (both the named caches and the "default" $http cache) when someone logs out. Right now I'm accomplishing this with location.reload(true), which certainly works, but it would be nice to achieve it without the reload if it's possible without totally changing the structure of the application.

To clarify, I'm aware that I can remove the cached values if I have a reference to the individual cache in scope, but what I want to do is to remove all caches, across the board, without necessarily having to know what they're all called.

like image 273
Casey Avatar asked Jul 01 '15 18:07

Casey


1 Answers

You can inject $cacheFactory and get the cache object from the factory constructor (eg: $cacheFactory.get('$http')) and use removeAll() to cleanup all the cache. Use destroy() if you want to remove the cache object altogether.

In order to get all the cacheObject id's you could use $cacheFactory.info() which will return object with summary info for each cache object {id:'cacheObjId', size:'cacheSize'}.

Example:-

angular.forEach($cacheFactory.info(), function(ob, key) {
   $cacheFactory.get(key).removeAll();
});

You could add removeAll/ destroyAll function to the cacheFactory so that you can use it anywhere else by decorating the $cacheFactory, something like this.

.config(['$provide',
    function($provide) {
      $provide.decorator('$cacheFactory', function($delegate) {
        $delegate.removeAll = function() {
          angular.forEach($delegate.info(), function(ob, key) {
            $delegate.get(key).removeAll();
          });
        }

        $delegate.destroyAll = function() {
          angular.forEach($delegate.info(), function(ob, key) {
            $delegate.get(key).destroy();
          });
        }
        return $delegate;
      });
    }
  ])

angular.module('App', [])
  .config(['$provide',
    function($provide) {
      $provide.decorator('$cacheFactory', function($delegate) {
        $delegate.removeAll = function() {
          angular.forEach($delegate.info(), function(ob, key) {
            $delegate.get(key).removeAll();
          });
        }

        $delegate.destroyAll = function() {
          angular.forEach($delegate.info(), function(ob, key) {
            $delegate.get(key).destroy();
          });
        }
        return $delegate;
      });
    }
  ])
  .run(function($cacheFactory) {
    var value = 123;
    $cacheFactory('cache1').put('test', value);
    $cacheFactory('cache2').put('test', value);
    console.log($cacheFactory.info());
    $cacheFactory.removeAll();
    console.log($cacheFactory.info());
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="App">

</div>
like image 110
PSL Avatar answered Oct 14 '22 00:10

PSL