AngularJS Best Practice - Templates vs. Javascript

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

  • The user downloads the Angular app. The main view has a subpage called "Order".
  • While the user is studying the main view, a new version of the application is deployed during production. The new version has a complete redesign of the Order page with new Javscript and HTML.
  • The user goes to the "Order" page. Javascript is already loaded by the browser in step 1, so the user is in the old version until the application is restarted. But a new template is selected from the server during navigation . So, now Javascript and the template are our synchronization!

Is my assumption that Javascript / HTML is not in sync, right?

If so, are there any recommendations on this issue?

I think one solution is to make Angular select all the templates when initializing the application. But it could be a performance penalty if the application has hundreds of HTML submissions.

+8
javascript angularjs
source share
7 answers

Thanks for the good answers.

It turned out that this problem was solved for us. Each time we launch a new release, all user sessions are deleted and users will be sent to the login page. This will cause the page to load, and new JavaScript / HTML will load.

+1
source share

I never wondered about this issue. One possible idea is to reuse a template known as asset versioning, where after the new version you will rename all your assets.

For example, instead of login.html you should use login-xyz.html as the name of the template. xyz may be a random value or a checksum of the file. The checksum may be slightly better, because if the new version is small (i.e. you only fixed a small error in one file), if the user loads any page other than a fixed one, he / she will not worry about reloading - all other files will be have the same checksums, they will work without interruptions.

Thus, when an obsolete Anguar application tries to get a template, it will receive an HTTP 404 error. In addition to this, you could write a simple $ http interceptor that would detect a 404 response and reload the page automatically (or suggest the user can do this).

There are modules that can rename assets, such as gulp-rev - but I have never heard of using this for Angular templates, however you can implement something like this yourself.

Of course, you might want both new and old versions of files to allow users to work without interrupting them with the update. Depending on your requirements. I assume that you are trying to avoid this.


Sample 404 interceptor (CoffeScript, as it’s convenient for me 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' 
+2
source share

I read about this problem for a long time, and one of the options is to do version control on the changed pages and the application.js file.

For example, in your version 1 of your application, you can use something like in your html file:

 <script src="js/angular_app_v1.js"></script> 

You can also use the templateURL template inside your routes.

 templateUrl: 'templates/view_product_v1.html' 

Therefore, when you deploy the new version, you will not overwrite the templates, and already working users will have the old version until you restart the browser, but will not have inconsistencies in the version.

0
source share

The top of assets using file names would be unattainable even for a third-party application.

Despite the fact that the web approach uses a lot of weight, you can look at the coordination of content. This is where calling the resource, usually the REST api returns the version of the resource, Content-Type: application/vnd.contentful.delivery.v1+json. . On the client, you can check whether the version is as expected. Therefore, if the client only knows how to download v1.1 and resource responses with v1.2, the user interface will know that it cannot handle this and must reload the page.

Another option is to download all the templates in the user interface. There are build processes in Grunt that you can run, such as https://github.com/ericclemmons/grunt-angular-templates , which will combine all your templates into a single file for delivery and then load them into $ templateCache, so requests never do not get to the server.

0
source share

If you have some kind of server language, you can create a filter in (.NET, Rails, Java or any other) and go through the version number with the requests of your template. If the version requested by the client is older than the deployed version, you should send an error message to the client. Your client will monitor this error ($ http interceptor) and force a page refresh to pull out new javascript code. (Perhaps first inform the user so that they know what is going on).

0
source share

You can preload all your templates into the $ templateCache template and serve them as one templates.js file. There is a gulp task for https://www.npmjs.com/package/gulp-angular-templatecache. Then your application will load all the templates in one request along with the application scripts at startup, so they will be synchronized. Read more at http://www.johnpapa.net/angular-and-gulp/ .

0
source share

It always makes sense to have a version number and use it when synchronizing resources. This is not only good practice for the use case you described, but also for another situation, for example, returning to a specific version or having two versions in real time and use (for example, so that some users can view the next version)

0
source share