I observed that often unexpected issues occurs with my apps as the user has templates cached in browser.
I tried $window.location.reload(true)
but even then chrome serves templates from the cache.
Is there an easy solution for this like adding a version query parameter to template URL dynamically using something like Interceptor?
Although on other similar question people sugested to use $templateCache
and load everything in one go. This isn't the solution I was looking for as it would increase app first load time by increasing app size and sacrifing on lazy loading provided by angular-ui-router.
So, below is what I did. Created a value provider for which contains version. This file is minified and include in index page and thus gets loaded along with the page.
angular.module('my-app').value('version', 'X.X.X');
I noticed that all my templateUrl in states, directives and even in ng-include is loaded via $http
service and thus at time of fetching template I can inject a query parameter. So I added following lines in app's config block:
angular.module('my-app').config(['$httpProvider', function($httpProvider){
$httpProvider.interceptors.push(['$q', 'version', function($q, version) {
return {
'request': function (request) {
if (request.url.substr(-5) == '.html') {
request.params = {
v: version
}
}
return $q.resolve(request);
}
}
}]);
}]);
So, all my templates are called with version number and now browser waits for new template to load if version is increased.
I periodically check for version update via an api. And if a new version is detected, I prompt user to reload the page. On user approval, I reload it via $window.location.reload(true)
Update
Following is snippet to check for new version. It can vary according to use case. As we have ad-hoc release cycle here, we check for new version on each window focus and also during first load.
angular.module('my-app').run(['$rootScope', '$window', 'version', 'configService', function($rootScope, $window, version, configService){
$rootScope.checkVersion = function () {
configService.getVersion().then(function (data) {
if (data.version != version) {
// show user a message that new version is available
promptUserForReload().then(function () {
$window.location.reload(true);
})
}
});
}
$window.addEventListener("focus", $rootScope.checkVersion);
$rootScope.checkVersion();
}])