I\'m currently working on a Angular/Ionic/Cordova project and we\'ve recently upgraded to the latest Ionic beta. From the version the project was using before, this introduc
Well this is an old issue, I will explain what really happens and how to solve it:
P.S: If you want to go straight to SOLUTION just scroll down right away.
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: SOLUTION $ionicHistory.clearCache(['login', 'map', 'home']); I cannot belive any Ionic developer didnt dug into the code before, or missed this simple datail. There's a lot of people who's aching for this.
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 that 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.
Are you searching for something like this?:
$ionicHistory.clearCache();
EDIT:
There is an issue in Ionic's github: Issue
In the state definition in app.js you can add cache:false
to disable caching (See Disable cache within state provider in the Ionic docs. Or, you can keep caching except when you know data has changed.
$state.go($state.currentState, {}, {reload:true})
$ionicHistory.clearCache().then(function(){ $state.go('app.fooState') })
Note, the latter requires clearCache to return a promise. See the changes I made in this pull request and compare the implementation of clearCache that you have now with mine: https://github.com/driftyco/ionic/pull/3724
You can also do it by setting cache:false
in your $stateProvider
:
$stateProvider.state('myState', {
cache: false,
url : '/myUrl',
templateUrl : 'my-template.html'
})
I stumbled across a similar scenario where logging in with another user was showing me stale/cached view. You can do cache: false
at the state definition level but that entirely disables cache for that state in your app.
What you can rather do is clear all the cached view and history when user enters the signin/login state of your application (as you said). Seems ideal.
// code inside your signin controller
$scope.$on("$ionicView.enter", function () {
$ionicHistory.clearCache();
$ionicHistory.clearHistory();
});