I have really basic use case in my app where I use AngularJS (1.0.8) for front end and Grails for back end. In the app layout I have a language switcher which allows the user to change the language. Switching the language, it does new http request to retrieve the page. Grails renders all language related stuff (i.e. labels) properly translated. This only works for Chrome, FF, and so but not for IE. IE renders proper language just for layout which is rendered by the main request.
I located the problem. I have defined $routeProvider where I load major of the app content. It is cached by default, therefore IE doesn't load templateUrl of $routeProvider because it loads them from cache:
myApp.config(function ($routeProvider) {
$routeProvider.
when('/', {controller: 'MyCtrl', templateUrl: '/eshop/myConfig'})
});
What I don't get is why it works in all other browsers.
I found some post how to clear cache but they doesn't work for me. Is there any solution for me? If not, I find $routeProvider completely useless for my use case.
Post I found:
angularjs clear history when view loaded
AngularJS disable partial caching on dev machine
Below should do it. You can manipulate angularjs's template caches by using $templateCache, so $routeProvider will load the template as new every time you access the controller.
myApp.config(function ($routeProvider) {
$routeProvider.
when('/', {controller: 'MyCtrl', templateUrl: '/eshop/myConfig'})
})
.controller('MyCtrl', function ($scope, $templateCache) {
$templateCache.remove('/eshop/myConfig');
// or
$templateCache.removeAll();
});
I was having the same issue with $routeProvider. And yes, the $templateCache does not help in this situation. Instead of keeping finding the real 'cache' source, I added the stamp parameter after the templateUrl.
In my code:
$routeProvider.
when('/', {templateUrl: '../views/home.html?v='+window.buildNumber, controller: 'HomeCtrll'}).
when('/report', {templateUrl: '../views/form.html?v='+window.buildNumber, controller: 'FormCtrll'}).
otherwise({redirectTo: '/'});
Sadly, I used a global variable "buildNumber" to save my life. Because I also use RequireJS for my AngularJS project, so this "buildNumber" will also be added to every dependency JS file by using the code:
require.config({
urlArgs: "v=" + window.buildNumber,
paths: {....}
});
Then every time the JS source or template html has been changed, I will only need to update that "buildNumber" in global scope. This is just a thought for the future updates in production environment. Hope this helps.
So the only solution I found was to completely disable cache for ajax queries. I found the solution here: https://stackoverflow.com/a/19771501/607038
myModule.config(['$httpProvider', function($httpProvider) {
//initialize get if not there
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
//disable IE ajax request caching
$httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
}]);
I don't like this solution because it disable cashing for the content which is really static. So if you have better solution than share it.
Related
I am running through a course at the moment on AngularJS and it has just introduced the concept of routing.
My problem is the app.config function is setup in app.js however, the function doesn't seem to ever be called and therefore the routes are not setup.
The common problem is the ngRoute not being declared however, it is. I'm not sure if there is a problem with the versions of Angular that I'm using but these were taken from the online course.
I have a public plnkr for anyone to view and have a look at http://plnkr.co/edit/L2FG4M?p=preview
(function() {
var app = angular.module("githubViewer", ["ngRoute"]);
app.config(function($routeProvider) {
// If we navigate to /main then the page used will be main.html and the controller
// MainController, if however something else is provided then we will
// redirect to /main as well
$routeProvider.when("/main", {
templateUrl: "main.html",
controller: "MainController"
})
.otherwise({
redirectTo: "/main"
});
});
}());
Any help is appreciated, I've exhausted my options now.
Thanks
Marc
In your MainController.js file, you defined a new module with same name as in app.js:
angular.module("githubViewer", []);
What you want to do is retrieve the already defined module. You can acheive that by removing the []:
angular.module("githubViewer");
Look here at the "Creation versus Retrieval" section.
So I have an AngularJS application in which I am attempting to bootstrap only after all of the data for the application is loaded. I need to be able to make the requests in JSONP format so I am attempting to load the $resource module by using a .run statement.
Here's how it looks:
(function(){
// Define our app
app = angular.module("GRT", ["ngResource", "ngRoute"])
.run(function($resource){
console.log($resource);
})
// Configure our route provider and location provider
.config(function($routeProvider, $httpProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: 'views/home.html'
})
.when('/customer-site-registration', {
templateUrl: "views/customer-site-registration.html",
controller: "customerSiteRegistration"
})
.otherwise({
redirectTo: '/'
});
// $locationProvider.html5Mode(true);
});
}())
Basically no matter what I do it wont run that run block. Any ideas?
Run blocks do not run until the Angular application is bootstrapped. I needed this to run before the bootstrapping.
In this setup the ng-app attribute was removed from the enclosing DOM element to prevent auto-bootstrapping and I was doing it manually after running some code.
Since I was only using it to get access to resource, I instead grabbed it manually like this:
var $resource = angular.injector(["ngResource"]).get("$resource");
Hope this helps someone else!
In my Angular app, I'm trying to render partials that load into the index page when a user clicks a link. It worked fine before with the following code:
//app.js in Angular
angular.module('myApp', [
'ngSanitize',
'ngRoute',
...
]).
config(['$routeProvider', '$locationProvider', '$sceDelegateProvider', function($routeProvider, $locationProvider, $sceDelegateProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MainController'});
$routeProvider.when('/File/:fileID', {templateUrl: 'partials/currentFile.html', controller: 'FileController', controllerAs: 'file'});
$routeProvider.otherwise({redirectTo: '/view1'});
$sceDelegateProvider.resourceUrlWhitelist([
'self',
'https://www.url.com/**']);
$locationProvider.html5Mode(true);
}]);
But when I add Express, it doesn't work:
var express = require("express");
var logfmt = require("logfmt");
var app = express();
app.use(logfmt.requestLogger());
app.use(express.static(__dirname + '/app'));
app.use('/bower_components', express.static(__dirname + '/bower_components'));
app.get('*', function(req, res) {
res.sendfile('./app/index.html');
});
This works fine if I just want to display the index page. When I add the following code though, it displays the plain HTML (of the partial), but without the CSS or Javascript.
app.get('/partials/currentFile.html', function(req, res) {
res.render('./app/partials/currentFile.html');
});
How do I go about rendering a partial with Express in a way that works with Angular?
I've tried looking at the Express api for get(), render and sendfile, but they weren't that helpful in my situation. Other users have asked a similar question on here before, but they usually involve another file that Express routes to and I'm wondering if I can do it without adding any extra files since it's already an issue with adding just a file to include Express.
The currentFile.html doesn't load any CSS or Javascript itself. Before I added Express, it was a partial that was loaded in index.html, which loaded all the extras.
Any help is appreciated. Thank you
I didn't fix the problem directly, but I worked around it. The problem was that I wanted to render a partial onto the index page. The overarching goal of the app is a single-page application, so in the end, it's just one page that matters.
It would have been nice to have different partials to render for testing, but alas nobody seems to know either what I'm asking or I'm complicating the issue. Either way, I've found a way around it by just getting rid of all the other partials and just redirecting all URL requests to the single page app.
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MainVideoController'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.when('/file', {templateUrl: 'partials/currentFile.html', controller: 'FileController', controllerAs: 'file'});
$routeProvider.otherwise({redirectTo: '/file'});
...
Note that the partials view1 and view2 DO NOT work when trying to visit domain.com/view1 or /view2.
I am just getting started with an angular project. We have a number of simple views and controllers, and have been using the mechanism provided by $routeProvider to map controllers to views. Upon updating to angular v1.2.0 the $routeProvider mechanism appears to be gone and replaced with something better. However, I have not been able to find a coherent code example showing how to make the switch.
What I have looks like this:
theApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/foo', {
templateUrl: 'views/foo.html',
controller: 'FooCtrl'
})...
What has that changed to?
Thanks
It is still $routeProvider, but they moved it out into a module. You need to add it to the list of dependencies for your app by injecting 'ngRoute'.
You can get the routing module with the others for http://code.angularjs.org/1.2.0-rc.2/
here.
I'm just starting out with Angular, so this might be a common newbie mistake but I am trying to achieve the following url format:
http://myapp.localhost/index.html#!/about
Which I believe should be the default for Angular?
This is my configuration:
angular.module('App', []).config(function($routeProvider, $locationProvider, VIEWS_ROOT) {
$locationProvider.html5Mode(false);
$locationProvider.hashPrefix = '!';
// Routing
$routeProvider.when('/', {templateUrl: './welcome.html', controller: 'WelcomeController'});
$routeProvider.when('/about', {templateUrl: './about.html', controller: 'AboutController'});
})
.run(function($rootScope) {
//...
});
In my html I have a simple anchor like so:
About
However when I click that anchor, the resulting URL constructed is:
http://myapp.localhost/index.html#/!/about
Which obviously fails to match any of my routes... a bit stumped on what's actually happening here, or what I'm doing wrong. I'm running off my local Apache instance under a vhost. There's nothing going on with mod_rewrite - so it looks like Angular is doing this.
It's a method to set the hashPrefix, not a property. $locationProvider.hashPrefix('!');