Problems refreshing angularjs changes on production server - javascript

I have a recurring issue that occurs when I make changes to my angularjs app. The problem is that I have to refresh the page if I want to seed the changes that I have made. This is a problem, because I don't want my users to have to refresh the page (they may not know to do this). They may think the site is broken. Is there some kind of angular directive or process that I can follow that will allow my UI changes to be reflected on my production server without my users having to refresh the page?

There are a couple of solutions you could look at,
There is a similar answer to your question here:
AngularJS disable partial caching on dev machine
To quote the accepted answer on that post:
"here's one way to always automatically clear the cache whenever the
ng-view content changes"
myApp.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
A non angular solution may also be found here:
Force browser to clear cache
To quote the best answer on that post (Fermin's answer):
If it's to view css or js changes one way is to append _versionNo to
the css/js file for each release. E.g.
script_1.0.css script_1.1.css script_1.2.css etc.
You can check out this link to see how it could work.
I hope these help.
EDIT.
To respond to your comment, I'm sorry the above hasn't worked.
Perhaps you could try implementing a websockets based approach, similar to Trello, whereby after a certain amount of time you ask the user to update their page to receive new updates to the system or to refresh if their socket connection has timed out? Depending on your setup you may find this tutorial useful: http://www.html5rocks.com/en/tutorials/frameworks/angular-websockets/

Using html2js you can more easily manage versioning of templates. It is a grunt plugin that will load all of your templates into a js file. Downside is all your templates get loaded regardless of need, upside is you have all your templates loaded ready to use on one http call and one point of caching for them. This way you can set up to rename your js file on new releases and bust the cache for templates on production. As for dev, the other answer here is sufficient.

Related

What am I doing wrong with Angular js manual bootstrap process?

I am using Angular 1.7.2 in a project i'm working on. (I prefer Angular 1.x)
I am doing the bootstrap process manually (because i'm adding scripts programmatically).
But, I am having 2 issues with the manual bootstrap process.
I have to use a setTimeout, else the bootstrap never works. And my problem with this is, the more files I add to my project, the longer i have to make the timeout.
Sometimes when I load my web page or refresh the site, not all my components are loaded. If i monitor the network traffic, i can sometimes see that the html files are not retrieved at all. And there are no errors in the console or anything.
It seems to me there must be something happening in the angular.boostrap process that is failing or getting stuck, but i can't figure it out.
For my first issue, why is the setTimeout required, is there a way to not need this?
Second, why does my site not load sometimes?
Could it be related to the OS locking the files temporarily because of all the source control, anti-virus, other services running on my computer? If so, how can i tell?
I put together a test project with relevant code here on github
I previously thought this was related to the routing, but it's not (see here), But it seems not related to angular-routing after all.
Any information would be much appreciated, this is driving me mad.
Update 1:
I have the code running here on github pages.
Best chance to replicate issue is to use google chrome, enter url, open dev tools (f12), then actually load url. Sometimes, the page doesn't load completely.
I have updated the test website to better reflect my project where I add scripts dynamically.
I think i found the solution thanks to a comment by igor
I moved my app.route.js file to be loaded before any of my angular component and directives and from what I can tell this solves my problem.
I will update the linked sample project too

Page created with ReactJs is not indexed by google

I have a news section created with ReactJs, each news post acts as an individual page.
Unfortunately Google is not indexing these pages because of REactJs. I tried to use the babel-polyfill webpack, but it's still not working. Also, I'm making my Ajax call BEFORE rendering the DOM.
Any other ideas for another workaround on this?
the google crawler won't wait for async requests to resolve, and because your pages are rendered on the users' client, they will appear to be empty pages.
You have two options. Either modify your app to render on the server, this is often called a universal app, or an isomorphic app. There are many tutorials for creating these. The other option is to pre-render static html from your code so that the crawler can see what should be there. There are numerous libraries you can use for this.
The first option is more extensible and probably preferable, but a bit more complex. So make the choice about whats more appropriate for you
It is not indexing them because they are bundled so tat they could be rendered inside your client's browser. What you ought to do is server side rendering.
You can find more about it here: https://medium.freecodecamp.org/server-side-rendering-your-react-app-in-three-simple-steps-7a82b95db82e

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.
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'
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.
I've read about this issue long time ago, and one option is to do versioning on changed pages and application.js file.
For example on your version 1 of your application you can on your html file use something like:
<script src="js/angular_app_v1.js"></script>
Inside your routes also version the templateURL
templateUrl: 'templates/view_product_v1.html'
So when you roll out a new version you won't be overwriting templates and users already working will have the old version until they reload the browser but won't have version inconsistences.
Versioning of the assets using the file names would become unmaintainable for even a medium sided app.
Although it is a heavy weight approach for web assets you could look into content negotiation. This is where the call for a resource, generally a REST api returns the version of the resource, Content-Type: application/vnd.contentful.delivery.v1+json.. On the client you can check that the version matches what it expects. So if the client only knows how to load v1.1 and the resource responses with v1.2 the UI would know it cannot process that and should reload the page.
Another possibility is to load all templates up front in the UI. There are build processes in Grunt you can run such as https://github.com/ericclemmons/grunt-angular-templates that will combine all of your templates into a single file for delivery and then load them into $templateCache so no requests ever get to the server.
If you have some sort of server-side language you can build a filter in (.NET, Rails, Java or whatever), and pass along a version number with your template requests. If the version requested by the client is older than what's deployed, you'd send an error to the client. Your client would watch for that error ($http interceptor) and force a page-refresh to pull down the newer javascript code. (Maybe show an alert to the user first so they know what's going on).
You can preload all your templates into a $templateCache and serve them as one templates.js file. There is a gulp task for this https://www.npmjs.com/package/gulp-angular-templatecache. Then your application will load all templates in a single request together with application scripts on start up, thus they will be in sync. Read http://www.johnpapa.net/angular-and-gulp/ for more info.
It always makes sense to have a version number and use it when syncing resources. It's not only a good practice for the use case you described, but also for other situation, such as rolling back to a specific version or having two versions live and usable (for example in order to let some users preview the next version)

How to architect a HUD in a Google Chrome extension?

I am trying to make a Google Chrome extension using content script.
My goal is to have a display at the top of the page (which is already working on my own pages) that can interact with the page.
I need things which are very complicated to put together in an extension, due to security policies :
Using require.js on the extension (that works for now, using this Github repo)
Using a templating engine to describe my display : I need to add a lot of content to the page and I don't think writing HTML in javascript would be a good workflow.
For my current version I use jade with my server, but this is not possible with an extension. I think I need to use something like Angular.js or Backbone.js, but I can't make them work on the content script.
I need a lot of communication between my extension and the page : For example I need to detect almost constantly mouse moves
I need communication with my server using socket.io
Every bit of functionality of my extension have been developed and tried in a standalone web page, but now I need to integrate it in a real extension and I am really stuck
So due to these requirements, I am wondering what would be the right approach for building this : putting it all in an iFrame (would the server-side communication work? And how to communicate with the page ?), or a way to make a templating engine work nicely in there, or a solution I didn't think of?
Try this:
Develop the HUD part as a standalone page that the content script will include in an iframe. You should be able to use Angular.js etc. with this, but you will need local copies of as much as possible and you'll need appropriate entries in the manifest.json to get it working in the extension. See/create other questions for the details.
Have your content script inject the code to monitor mouse-moves, etc. into the target page. Have this code digest and summarize the data, so it's not spamming the system. Maybe message the summaries to the HUD page and/or content script five or six times a second.
After that, it should just be a matter of getting the pieces working, one at a time. Break it down to specific problems and ask a question on one specific problem at a time (If you can't find the answers in previous questions).
I'm pretty sure what you appear to want is do-able, but the details are too broad for a single Stack Overflow question.

Comments framework for single-page JavaScript MVC application, like Disqus for AngularJS

I am working on single-page AngularJS application that doesn't have any backend but use mongolab for storing data.
It also makes all the calls (like CRUD and filtering) by using the same URL, changing only the part after hashbang (#).
So the URL looks like mysite.com/#!/ for main page, mysite.com/#!/view/:id for viewing the story, mysite.com/#!/edit/:id for editing it etc.
I would like to use some 3rd party hosted commenting tools to allow users to comment each story. I've tried Disqus and Livefyre, but they're tied to URL before hashbang, so all the website pages is just the single page for them. I've tried to reload Disqus, but it tries to re-attach it's own javascript every time, so loading it multiple times lead to js errors. I have looked at Facebook Comments, but it don't even have a page ID, so the comments are only per site.
Disqus have it's own API, but there are no JS bindings to the newest (and only) version of API (3.0), and creating bindings by myself looks a bit excessively.
Does anyone know good JS comments framework which I could use along with AngularJS or any hosted solution that could help?
http://docs.angularjs.org/ already do most of what you described here. Disqus works quite well for us. Feel free to look at the source code. Everything is on github.

Categories