I am trying to reload the page mannually from the browser but it doesn't work and says
Cannot GET /rate/4
My route:
angular.module('routing')
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'app/views/index.html'
})
.when('/rate/:cid', {
templateUrl: 'app/views/rate.html'
})
.otherwise({
'redirectTo': '/'
});
$locationProvider.html5Mode(true);
});
My assumption is that when I am reloading the main (index.html) is not loaded which is my base html file.
You do not have an angular problem, you have a server problem.
You're essentially working with a single page application.
When the server receives a request for rate/4 it must return index.html (or whatever the name that your main page is).
How you solve this will depend upon what platform you've implemented your server in.
For example, if you were running a node express server, you would have this kind of routing code:
app.get(/^\/rate\/.*/, function(req, res) {
// This matches a known pattern for a client-side route
res.sendFile(__dirname + '\\public\index.html');
});
Related
I am facing a weird issue with angular and express,
I have a very simple routing on app.js as below :
app.get('/partials/:name', routes.partials);
app.get('*', routes.index);
also this is on my angular routerprovider :
$routeProvider.
when('/', {
templateUrl: '/partials/home'
}).
when('/contact', {
templateUrl: '/partials/contact'
}).
otherwise({
templateUrl: '/partials/error'
});
now the problem is, if I enter below invalid url, it goes to error page [OK]
http://www.devnest.io/someInvalidpath // it will go to /partials/error
But if I enter an invalid url with two level path (or more) page will hang [NOT OK]
http://www.devnest.io/someInvalidpath/AnotherInvalidPath // page will hang without error
and in the developer tools, it likes infinite loop and page call, like this picture :
also there is no error on node.js or angular ...
I am really confused, can anyone help me, on which part my routing is not correct ?
Thanks,
Try
app.use(routes.index);
instead of
app.get('*', routes.index);
I am using NodeJS + expressJS on server and AngularJS on client
AngularJS controller have the following routes:
app.config(function($routeProvider,$locationProvider) {
$routeProvider
.when('/field1/:id', {
controller: 'ctrl1',
templateUrl: "/view/mainpages/field1.html"
})
.when('/field2/:id', {
controller: 'ctrl2',
templateUrl: "/view/mainpages/field2.html"
})
........... many many
.when('/', {
controller: 'ctrl0',
templateUrl: "/view/mainpages/index.html"
})
.otherwise({redirectTo : '/'});
NodeJS static:
app.all('/*', express.static(__dirname + '/client'));
How to make the server redirects all the static pages on their paths relative to the root, in the case when the call goes directly through this link.
example:
server:3000/field1/23 must call server:3000/client/index.html
and index must upload JS like server:3000/js/cntr1.js
Upd: I found a solution to the problem. But it looks ugly as a crutch
app.get('/field1/([0-9]+$)', function(req, res, next) {
req.url='/index.html';
next();
});
app.use('/field1', express.static(__dirname + '/client'));
Perhaps there is a more elegant solution?
In expressjs, you can define the route using regular expression pattern matching. That means, anything under a specific set will always return the same page from the server side, and you will let angular decide what exactly to display or do which action.
Its not a great idea to redirect everything at / to same page as you need to manage your assets and they exist on the / part too , instead its a good idea to use a subdir which is easy to manage
Following snippet will redirect everything under the app path to the same page on server side
app.get('/app/*', function(req, res) {
res.send('app_index');
})
if you do not want to be limited to one app dir, instead you have a number of different root level dirs, all of which need to point to the same page, you can do something like this
app.get('/(app|server|client|form|dashboard)/*', function(req, res) {
res.send('app_index');
})
I am using $routeProvider service in my angular js but problem is on templateURl it provides me error
from server here is the error what i received
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
angular.js:11594 Error: [$compile:tpload] Failed to load template: /Testing/TestCompleted
and here is my angular code for app.js
var app = angular.module('app', ['ngRoute']);
app.controller('CreateController', CreateController);
app.config(function ($routeProvider) {
$routeProvider
.when('/',
{
templateUrl: "/Testing/TestCompleted",
controller:"AppCtrl"
})
});
app.controller("AppCtrl",function ($scope) {
$scope.newmodel = {
}
});
I found the solution the view is only returned by server by using route we can only get html view not cshtml because that is provided when action is called.
The url is giving a ERROR 500. This is that there is something wrong in de code of the page. Please attach your debugger and go to the url "/Testing/TestCompleted" with a browser and check what is wrong.
Edit:
If the url is really the right one. Please try the following:
angular.module('app', ['ngRoute'])
.controller("AppCtrl",function ($scope) {
$scope.newmodel = {}
})
.config(function ($routeProvider) {
$routeProvider
.when('/',
{
templateUrl: "/Testing/TestCompleted",
controller:"AppCtrl"
})
});
So that the controller is registerd before you do your config as in the example from Angular (https://docs.angularjs.org/api/ngRoute/service/$route).
The address of the template is likely wrong. I never had to use a format such as '/....' .
You probably want 'Testing/TestCompleted' if the directory Testing is at the root of your project (or './Testing/TestCompleted' both should work).
EDIT:
In any case you are probably using an html file for the template, with an extension .html . So use 'Testing/TestCompleted.html' for instance.
I have started an application where I use Express 4.0 server. I have set up the routes based heavily on a tutorial on scotch.io (http://scotch.io/tutorials/javascript/build-a-restful-api-using-node-and-express-4), builiding a backend api to serve the front end SPA (angularjs). Here is an extract of the backend router:
router.route('/users')
.get(function (req, res) {
User.find(function(err, users) {
if (err) {
res.send(err);
}
else {
res.json(users);
}
});
})
Further down
// home page route (http://localhost:8080)
router.get('/', function(req, res) {
res.send('API ROOT');
});
app.use('/api', router);
From the frontend i use just a get to get the users from the api:
$http.get('/api/users')
.success(function(data) {
$scope.users = data;
});
and the angular routes are set up like this:
.when('/', {
templateUrl: 'views/home.html',
controller: 'MainController'
})
.when('/users', {
templateUrl: 'views/user.html',
controller: 'UserController'
})
The index.html has a link to /users.
When starting the server and goint into localhost:8080 it loads fine, and clicking the users loads the user.html view and lists the users.
However, if i click refresh when browser is in localhost:8080/users
I get:
Cannot get /users
Is it a controller issue?
Or is it a problem with backend routing?
Any feedback/suggestions would be very welcome!
Searching some more, I see that there are several sollutions that might fix this:
Either on the frontend (angular routes part) adding this to the end:
// >>> redirect other routes to
otherwise({
redirectTo: '/'
});
Or on the backend (after all your routes):
app.get('*', function(req, res){
res.render('index.html');
});
Which sollution is better (or is it reccomended to use both...?)
You should use both.
You need to provide a catch-all / wildcard route to your express application such that any routes that are not explicitly matched will return the index page which will load Angular and allow your Angular routes to then take over. Note that this should always be your last route (they are parsed in order).
app.get('*', function(req, res){
res.render('index.html');
});
Then in your Angular app you should have a default route to catch any un-matched routes on the client side. This route will come into effect if the application is already loaded but an unknown route is encountered whereas the server side solution above will handle any direct requests.
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'home.html',
controller: 'homeCtrl'
}).
otherwise({
redirectTo: '/'
});
}]);
I have an angular app with a directory structure
app
..views
....partials
......main.jade
......foo.jade
....index.jade
and routes defined like:
'use strict';
angular.module('myApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
'firebase',
'myApp.config'
])
.config(function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
templateUrl: '/partials/main',
controller: 'MainCtrl'
})
.when('/foo/:fooName', {
templateUrl: '/partials/foo',
controller: 'FooCtrl'
})
.otherwise({
redirectTo: '/'
});
});
I'm using express on the server side and the relevant code is:
// server.js
app.configure('development', function(){
app.use(express.static(path.join(__dirname, '.tmp')));
app.use(express.static(path.join(__dirname, 'app')));
app.use(express.errorHandler());
});
app.configure('production', function(){
app.use(express.favicon(path.join(__dirname, 'public/favicon.ico')));
app.use(express.static(path.join(__dirname, 'public')));
});
app.get('/', routes.index);
app.get('/partials/:name', routes.partials);
//routes.js
exports.index = function(req, res){
res.render('index');
};
exports.partials = function(req, res){
var name = req.params.name;
res.render('partials/' + name);
};
The main route "/" loads fine and when i click to "/foo/bar" the partial view foo.jade loads as expected. However, when I try visiting "/foo/bar" directly in the URL i get a 404 response from Express "cannot GET /foo/bar" which makes sense since there's no route like this defined in express. However, I thought this was the whole point of defining the angular router..i.e. it's supposed to intercept this request and actually ask for "/partials/foo".
I tried adding
//redirect all others to the index (HTML5 history)
app.get('*', routes.index);
but it didnt solve the issue and seemed to be catching even the requests for static js assets and responding with the contents of index.html which is pretty bad.
I'm sure I'm doing something wrong. How can I fix things so that I can directly visit the URLs?
The reason routing is behaving like this is html5mode turned on.
Notice the line: $locationProvider.html5Mode(true);
You need to understand that when you try to access "/foo/bar" directly your browser sends HTTP GET request to this URL. When you try to access this url via link clicking, like you said, Angular is intercepting this action and calls History.pushState that only updates browser's link.
What you need to do in order to make html5mode routing work is implementing url rewrite. Every request has to be redirected to your index file that bootstraps AngularJS application, but this needs to be done on your server. Angular will render the desired page by itself.
Check out connect mod rewrite grunt task that does exacly that.
You can also you this middleware directly.