6

I know how to make the cache cleared for view :

  .state('app.list', {
    cache : false,
    url: "/lists/:listId",
    views: {
      'menuContent': {
        templateUrl: "templates/listDashboard.html",
        controller: 'listDashboardCtrl'
      }
    }
  })

, but I need something else - delete all the cache for the app in controller method. how to do it?

GO VEGAN
  • 1,113
  • 3
  • 15
  • 44
  • http://stackoverflow.com/a/33964486/3561568 Please see my other answer. pretty simple solutions $ionicHistory.clearCache() now returns promise so you can ensure cache is cleared – Tanweer Nov 27 '15 at 20:42

3 Answers3

13

I found a solution, Wrap the clearCache and ClearHistory in a $timeout. Something Like this.

$scope.logout = function(){
      $location.path('/signin')
      $timeout(function () {
          $ionicHistory.clearCache();
          $ionicHistory.clearHistory();
          $log.debug('clearing cache')
      },300) 
}

Edit:Changed Timeout seconds

VizardCrawler
  • 1,343
  • 10
  • 16
Karan Kumar
  • 2,655
  • 19
  • 36
  • This worked for me. So strange that this has to be done... I only gave mine a 100 millisecond timeout and it works fine. – Ben Sinclair Sep 21 '15 at 05:44
2

You can use $ionicHistory. From documentation:

clearCache()

Removes all cached views within every ionNavView. This both removes the view element from the DOM, and destroy it's scope.

In your listDashboardCtrl write this:

function listDashboardCtrl($scope, $ionicHistory){
  $ionicHistory.clearCache();
}
Farkhat Mikhalko
  • 3,565
  • 3
  • 23
  • 37
  • 2
    Doesn't work. In my app I call $ionicHistory.clearCache() after the user logs out. When the next user logs in, the old data is still there in the view. – Android Noob Apr 29 '15 at 17:44
  • I am having the same issue, did you find any solution ? @AndroidNoob – Karan Kumar Jun 03 '15 at 06:25
  • 1
    Yeah i figured it out a while ago. In my login page, I put the history/cache clearing methods inside the $scope.$on('ionicView.enter', ...) block. – Android Noob Jun 03 '15 at 17:42
0

Well this is an old issue, but for anyone that's coming 2017 or later I will explain what really happens and how to solve it:

The code of $ionicHistory.clearCache():

clearCache: function(stateIds) { return $timeout(function() { 
$ionicNavViewDelegate._instances.forEach(function(instance) { 
instance.clearCache(stateIds); }); }); }

So, as you can see, it takes 1 parameter cllaed stateIds which is an array of stateId. Indeed i struggled to find out that stateId is nothing more than stateName.

So, let's go deeper. The code of $ionicNavView.clearCache which is used in the line above "instance.clearCache(stateIds)" is:

self.clearCache = function(stateIds) {
    var viewElements = $element.children();
    var viewElement, viewScope, x, l, y, eleIdentifier;

    for (x = 0, l = viewElements.length; x < l; x++) {
      viewElement = viewElements.eq(x);

      if (stateIds) {
        eleIdentifier = viewElement.data(DATA_ELE_IDENTIFIER);

        for (y = 0; y < stateIds.length; y++) {
          if (eleIdentifier === stateIds[y]) {
            $ionicViewSwitcher.destroyViewEle(viewElement);
          }
        }
        continue;
      }

      if (navViewAttr(viewElement) == VIEW_STATUS_CACHED) {
        $ionicViewSwitcher.destroyViewEle(viewElement);

      } else if (navViewAttr(viewElement) == VIEW_STATUS_ACTIVE) {
        viewScope = viewElement.scope();
        viewScope && viewScope.$broadcast('$ionicView.clearCache');
      }

    }
};

And as you can see in the code, this clearCache DOES NOT CLEAR ALL CACHES, instead, it destroy all cached views that matches a value in the stateIds array. If there's no parameter IT JUST DESTROY THE ACTUAL VIEW.

So the solution for this, using just the Ionic way is to call $ionicHistory.clearCache() with all your state names in an array as parameter.

E.g: $ionicHistory.clearCache(['login', 'map', 'home']); I cannot belive any Ionic developer didnt dug into the code before, or missed this simple datail. I Hope someone takes advantage of this, even being so late.

UPDATE: Just to make it crystal clear, i want to point out where the bug itself is (if we can call it bug), maybe can be handy for devs:

self.clearCache = function(stateIds){

[...]

 var viewElements = $element.children();

} What the whole function does is basically:

Get all elements using JQLite Loop the elements Check if an element equals one in the StateIds array and destroy it; go to next element. Check if element in the loop is cached or active, and in both true cases destroy it I wont dig deeper into this but debugging it i could see that the elements gotten from var viewElements = $element.children(); is not an array of all your views content, not even the cached ones, intentionally or not it does not loop through out all your states to clear all those that matches 'ACTIVE' or 'CACHED'. If you want it to loop through ALL your states and destroy all cached views and data you need to explicity pass the stateIds array parameter.

Besides there's another strange behavior, because when i was debugging it i saw when the var viewElements array was filled up with 2 elements, and these 2 elements were from the same state, one resolved to 'CACHED' another resolver to 'ACTIVE', even resolving to the 2 types used in the if conditions the cache was not cleared at all.

I personally think that this is somekind wrong implemented or is wide used wrongly. The fact is that there's a lot of people cracking their heads on this and devs don't even give this simple explanation.

Marco Silva
  • 564
  • 5
  • 15