Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS best practice - Templates vs Javascript

Per default, Angular fetches the HTML templates from the server when the user navigates to a route. With that in mind, imagine this scenario:

  • User loads the Angular app. The main view has a subpage called "Order".
  • While the user is studying the main view a new version of the app is rolled out in production. The new version has a complete rewrite of the Order page with new Javscript and HTML.
  • The user navigates to the Order page. The Javascript is already loaded by the browser in step 1, so the user is on the old version until app is reloaded. But the new template gets fetched from the server on navigation. So now the Javascript and template are our of sync!

Is my assumption that the Javascript/HTML is out of sync, correct?

If so, are there any best practices related to this issue?

I guess one solution is the make Angular fetch all the templates on app initialization. But this could be a performance penalty if the app has hundreds of HTML views.

like image 484
HoffZ Avatar asked Feb 27 '15 15:02

HoffZ


2 Answers

I've never wondered about that issue myself. One possible idea would be to reuse the pattern known as assets versioning, where upon new release, you rename all your assets.

For instance, instead of login.html you'd use login-xyz.html as a name of a template. xyz could be a random value, or a checksum of the file. Checksum might be a slightly better option because if the new release is small (i.e. you fixed just some small bug in one file), if user loads any page but the fixed one, he/she will not be bothered with a reload - all other files will have the same checksums, they'll work with no interruptions.

This way, when an outdated Anguar app tries to fetch a template, it'd get a HTTP 404 error. As an addition to that, you could write a simple $http interceptor, which would detect a 404 response, and reload page automatically (or offer user an option of doing so).

There are modules which are capable of renaming assets, such as gulp-rev - but I never heard of using that for Angular templates. You might implement something like that on your own, though.

Of course you might want to keep both the new and old versions of files to allow users to work without interrupting them with a refresh. Depends on what your requirements are. I assume you're trying to avoid that, though.


Sample 404 interceptor (CoffeScript, as I have it handy now):

m.factory 'notFoundInterceptor', ($q) ->
  return {
    responseError: (response) ->
        if response?.status == 404
            # Reload, or warn user
            return $q.defer()

        # Not a 404, so handle it elsewhere
        $q.reject response
  }

m.config ($httpProvider) ->
  $httpProvider.interceptors.push 'notFoundInterceptor'
like image 62
kamituel Avatar answered Sep 22 '22 16:09

kamituel


Thanks for good answers.

It turned out that this problem solved itself for us. Every time we roll out a new release all the users sessions gets deleted and users will be sent to the login page. This will trigger a page load and fresh JavaScript/HTML gets loaded.

like image 43
HoffZ Avatar answered Sep 21 '22 16:09

HoffZ