Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle site update with angular?

I have an angular app hosted on github pages. When I push out a new version users who have the site partially loaded can experience problems until the page is refreshed.

I think this is maybe because the users browser has downloaded the updated version of a view. The updated view uses a new directive which is not in the modules that they had loaded in their browsers.

I can think of a multitude of hacks to get around this but surely it must be a common thing. Is there a standard way to deal with this or to structure the app to avoid these problems.

like image 426
Adam Butler Avatar asked Nov 08 '22 22:11

Adam Butler


1 Answers

Assuming you minify your client side javascript and/or css assets you can check whether a script or stylesheet that was included in the html in the form of:

<script src="scripts/vendor.a2d3cfb2.js"></script>

Still exists on the server - if does not exist you can prompt the user to reload the app as it may be an indicator of new version of the application being deployed.

Note that this requires using a file that changes frequently if not always whenever a new version of the application is deployed. If you don't have such file or you application is deployed frequently with small changes you can use your index.html to verify cache busters in the links to stylesheets, javascripts in a fresh version fetched from the server have changed.

A rough sketch of a check for an updated script file:

var module = angular.module('test', []);
module.run(function($interval, $http) {
  var intervalHandle;
  var scripts = [].slice.call(document.scripts);
  var testFile = scripts[0]; //use resource whose uri changes with each deploy
  intervalHandle = $interval(function() {
    $http.head(url + '?' + Date.now()) //scripts may be large avoid downloading content
      .catch(function(response) {
        if (response.status === 404 || response.status === 410) {
          alert('New version may be deployed.');
          $interval.cancel(intervalHandle);
        }
      });
  }, 5 * 1000 * 60); //every five mnutes

});
like image 139
miensol Avatar answered Nov 14 '22 22:11

miensol