Angular templates and cache invalidation - angularjs

I am working on a project that uses Angular1, we hit the problem where when we change an html template the users will not see the change until a hard refresh is performed. Ideal would be to have the cache service to check a timestamp and invalidate the cached file. As an example now I edited a template used by the $stateProvider.
My questions is what solutions or best practices are used to solve the problem?
P.S since our JS files are combined in 1 file we fixed the problem there by appending a timestamp in the script tag from our PHP backend

Interesting question! We've had the same issue in a project that uses Angular1.x. We solved it using angular-cache-buster.
It basically helps you put a httpInterceptor. All you need is have ngCacheBuster in module dependency injection, and inject httpRequestInterceptorCacheBusterProvider in the .config of your app to set the match list.
For example,
httpRequestInterceptorCacheBusterProvider.setMatchlist([/.*api.*/], true);
this tells it to cache everything except REST api requests. You can learn more about the configuration here.

Related

$templateCache, ng-template and caching issues - angularjs

I am trying to cache my angularjs application's html files, following this suggestion: https://gist.github.com/ProLoser/6181026.
I am appending a dynamic cache key like ?v=123456790 to all html files (except those in the templates directory used by angular ui bootstrap).
For partials in their own files, i.e. app/views/customer/customer-history.html this works perfectly. However, for partials in script form, e.g. <script type='text/ng-template' id='customer-history'> the template is not found and a server request is made, resulting in a 404.
E.g. localhost:8080/customer-history/?v=1234567890
I can see the templates in question are in the $templateCache. The ones using ng-template are just the name ie customer-history whereas the separate files ones are by path app/views/customer/customer-history.html as you might expect.
It's a large app so going through and moving them all to their own files etc would not be trivial. I've scoured everywhere and I'm not turning anything up so I'm guessing it's something basic with how the templateCache is implemented.
I'm using gulp-templatecache plugin during the build process but the docs are quite limited and I don't think the issue lies there.
My current solution is just to skip the offending templates for now in the function appending the version number by decorating an inCache function onto the $templateCache factory and using it during the check to append the cacheKey. But I feel this is kind of missing the point.
Answering my own question here.
Because the script tags are part of the containing html file that gets loaded into the $templateCache, the script is already there. When a request is made for the templateUrl, it shouldn't have the cache busting appendix.
The simplest way to avoid all this is to just set the cache busting hash or string on the "templates.js", or whatever the template output of the build process is. That way the entire file gets invalidated and reloaded as needed.

What is the best way to update an angular application?

Our team is constantly working on an angular application, and every week or 2 we update it with new features or correct some bugs that came out.
We are using a C# backend with webservices.
QUESTION: When we update the application on the server, we sometimes (this doesn't happen all the time) get the problem that user is still seeing the old HTML and functionalities. What is the way to solve this?
I didn't find this on google, maybe I'm not looking for the right terms,
any help is appreciated.
Users have to clear their cache to get the new version of the application.
What you are seeing are cached copies of the JS files (possibly HTML partials too).
When the browser parses the HTML page, it makes the request for getting the JS resource and looks at various information before deciding to retrieve either the cached copy (if any) or whether to query the server again.
You can find some extra details on the Google fundamentals on HTTP caching
A solution I have been adopting myself is to set the cache headers to cache the file for a very long period, and then use tools in the build to version the file either on the filename or with a request parameter.
I have used grunt-cache-breaker and found it to serve well for this purpose. I know there is a gulp equivalent too
The most common way to make sure cached versions of your javascript aren't used is adding the version as a parameter in the reference to the script like so:
<script src="/app.js?v=v1.0"></script>

I am trying to creating a polling app on the mean stack. I think my routing is messed up but I am not sure

I am trying to create the polling app described in this tutorial here.
I have step 2 finished, and I am about to start step 3(once my application is running properly) which is to incorporate the DB portion. My application is not behaving like the application listed in the tutorial currently though.
I have scanned my code numerous times and debugged it and still cant seem to catch what is throwing it off. When I run the application it runs fine, but none of my partials are being displayed only what is provided in the inital index.html view, so it is simply showing my blank navbar.
I have provided my git repository. If anyone has a moment and can take a look at it. Thank you for your time in advance.
Some of the key things I fixed in my pull request:
You need to include angular-route.js as a separate file now, and have your module depend on ngRoute.
You were missing quotes around the first $routeProvider in the following line:
.config(['$routeProvider',function($routeProvider){
You now need to register controllers using a name (string) with the module, rather than using global functions.
app.controller('ControllerName', function ($scope, ...) { ... });
You also forgot to actually reference a few of the JS files you need in index.html using <script> tags.
There are other small things, but see the PR for the full details. I also changed the way bower components are done.

AngularJS $route service undesirable hash issue

I'm working on a big project. This project already has complicated structure. Most pages are generated on server-side with Twig.
Now we move the project to AngularJS.
It is not possible to use angular-way routing on whole project just now. But somewhere, it is necessary.
And here comes our trouble.
If I add 'ng-app' in html tag, for example, on some pages angular add hash in url.
And what is strange for me, that it's not everywhere.
On start page (project/profile9868766), url is clear as it is. But on some other (project/community/list), angular does something like that: project/community/list/#list .
And it is extremely undesirable.
There are no any angular routes, configured in $route service yet.
Please, help me to find out what causes that behavior, and what should i do to make all the things to go right way.
I want to add ng-app in html tag and not get any troubles with existing code, that may use hashes. And I want to use angular directives, controllers and other stuff, including $location service to set and track hashes on some pages. And later move everything to Angular and only after that start using Angular routes.
Thanks!
PS: English is not my native language, sorry about some weird constructions and mistakes. ))
Make sure to turn on html5mode
http://docs.angularjs.org/guide/dev_guide.services.$location
But the hash is inevitable on non-html5 browser.
The latest version of angular (v1.0.7) seems to have fixed this issue.

Loading constants from a web-service without using resolve or manually bootstrapping the app

I am working on a small piece of an angular project and need to define some constants that are derived from values in a database. I have a REST endpoint that delivers the data I need, but I can't figure out how to load the values before the app gets automatically bootstrapped.
I cannot modify the application to a manual-bootstrapping process. Typically a resolve would be used upon navigation, but I have other components (like modals) that use the constants that aren't necessarily part of any route.
What would be ideal would be some sort of "resolve", but at the application layer. I do have the ability to load npm and bower packages, but anything that changes to a 'manual' bootstrapping method isn't allowed.
In that case I can recommend you to use a $rootScope. I don't understand very well your needs, but everything that is stored in $rootScope will be available in all views. Just fill it with your REST service inside the first or main view of your app. Although, it is important to understand that if you refresh you page, the $rootScope will be as well refreshed, this is, all of your REST calls will be launched again. (Navigating inside angular views is NOT refreshing the page unless you ask for it using window.reload() or similar; it is just the same page with a new controller)
To avoid this last behavior (page refresh) you could also use local Storage, which is basically a small amount of memory inside your browser where you can save any data that you want to keep regardless of your page refreshes. I used in one of my projects this library: https://github.com/grevory/angular-local-storage
It was useful for saving permanent stuff until user logs out.
Hope it helps! And sorry if I am answering something not useful for you
Cheers
It seems that the only way to effectively load some values from a service prior to the app starting is to make the service-call to and then manually bootstrap the app. The idea of an app-wide "resolve" doesn't seem to exist.

Resources