$routeProvider stopped working from absolute path - angularjs

Weird thing happened. It was working fine. I have not changed anything related to routes, but it stopped working when accessed using an absolute path.
Here's what I have in app.js:
myApp.config(function($routeProvider) {
$routeProvider.when('/', {
templateUrl: '/app/views/entry.html'
})
.when('/orderstatus/:routeParam', {
controller: 'controllerController',
templateUrl: '/app/views/page.html'
})
...etc.etc
If I access "orderstatus" with parameter from inside the website, e.g. I navigate to the website.com, then access this route, it works fine.
But if I access it using an absolute path, e.g.
https://website.com/index.html#/orderstatus/24c98f38-190d-4a0c-86a2-49fb5f4d68fb
it redirects back to https://website.com/index.html#/
It used to work fine. I need this direct path because we email the customer order confirmation, and they can click on the link and get to the order confirmation page directly.
Now it does not work all of a sudden. I am totally perplexed as to why this could have happened. Like I said, it worked before.
If that matters, I am referencing a CDN at
https://code.angularjs.org/1.4.6/angular-route.min.js
and regular angular js at:
https://code.angularjs.org/1.4.5/angular.min.js

Live and learn.
One of my directives that's included in index.html was redirecting to the root on error.
ng-route was working fine and as expected.

Related

AngularJS Routing not working when url typed

So, I'm pretty new to AngularJS and I'm trying to use AngularJs ngRoute in my application.
It all works smoothly when I start at the application homepage:
http://localhost:8080/appName/
And when I click on links from this point it works smoothly.
However, when I type a URL that I know exists/works, it gives me a 404 error. If I go to that link by using the application instead of the url it loads fine, even though it has the same url.
Eg. http://localhost:8080/appName/search
will give a 404, even though that is the same url that is the default redirect.
Indeed, the only url that will load by typing in the location is the base URL I mentioned above.
My app.js looks like this:
app.config( ['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider){
$routeProvider
.when("/search", {
templateUrl: "search.html",
controller: "SearchController"
})
.when("/results", {
templateUrl: "results.html",
controller: "ResultsController"
})
.when("/browse", {
templateUrl: "browse.html",
controller: "BrowseController"
})
.otherwise({redirectTo:"/search"});
//This gets rid of the # on the urls to the templates
$locationProvider.html5Mode(true);
}]);
I am hosting this on a glassfish4 server.
Is there something obvious I am missing/misunderstanding about how ngRoute works? Is there some setting that I am missing?
All help appreciated...
EDIT 1: As #Matthew Green below says, I need to configure the webserver to return the index.html for all pages below
http://localhost:8080/appName
I know I am being completely dense here, but where abouts is this configured? I am hosting the code in a MAVEN Jersey-Quickstart-Webapp.
When you use ngRoute, you are using javascript to handle routing to create a SPA. That means you need to hit a real page that loads your routing for your application to know what page to route to.
For example, your http://localhost:8080/appName/ should be routing to your index.html which would contain the javascript for your routing. With that page loaded it knows how to handle the links you have in your application. However, if you were to go directly to http://localhost:8080/appName/pageName you also need that to load index.html, as it is the one that loads your routing. Once your routing is loaded it should direct you to the correct page in your application. Without redirecting in place, http://localhost:8080/appName/pageName is not a real page and therefore correctly returns a 404.
Knowing this, the thing you have to figure out is what kind of server setup you have to configure the appropriate redirects for everything under http://localhost:8080/appName/ to go to your index.html page.

Relative URL for RouteProvider in AngularJS

I have a website that will likely be placed within a directory in IIS. When I am running the application on my computer through IISExpress, the routes are relative to the base URL, so I can just define my routes as follows:
$routeProvider.when("/home", {
controller: "homeController",
templateUrl: "/app/layout/myView.html"
});
This gives me the following URL:
http://localhost:60847/#/home
When I put publish this site to our server, I have the URL:
http://dev.mysite.com/MyApp/#/home
However, I keep getting an error "Failed to load template: /app/layout/myView.html". When I look at Fiddler, I can see that it is trying to pull in the template from http://dev.mysite.com/app/layout/myView.html instead of from http://dev.mysite.com/MyApp/app/layout/myView.html. I have tried rewriting the templateUrl as ../app/layout/myView.html, as ~/app/layout/myView.html, and as ../../app/layout/myView.html. No matter what I do, I still end up trying to pull it from the parent folder instead of from MyApp. I have also tried setting a web.config setting and using that to put a prefix on the templateUrl, but it doesn't seem to want to run that code prior to loading the template. Finally, I have tried setting up a function for the templateUrl, but the way I have that stored in the web.config file creates timing issues with pulling the information.
It seems as if this must be a common issue that I am making overly complicated. Is there a way to make this a relative URL?
You should add to your HTML's head:
<base href="MyApp/" />
See this documentation page for more details.

Changing root URL Angular UI-Router

I'm learning Angular by rewriting a JS web application in Angular, and I'm having some struggles with replacing ngRoute with ui-router. Although I realise that it is designed to build SPAs, I'm only rewriting a branch of pages in angular.
My current understanding is that ui-routing requires you to define the root route '/'. Mine looks something like:
var memberPage = angular.module('memberPage', ['ui.router']);
memberPage.config(['$stateProvider', function($stateProvider){
$stateProvider
.state('userpage', {
url: '/',
template: '<h1>test</h1>',
controller: 'dashBoardController'
})
}]);
The problem - I think - is that the user never hits this route. The user logs in and is being redirected to /users/:id, and the page that is being rendered with this route loads the angular app.
The (sinatra) routing that happens on the server side before the angular app gets loaded:
get '/' do
redirect "/login"
end
get '/login' do
redirect_to_userpage_if_logged_in
erb :login
end
post '/login' do
redirect '/login' unless user_exists(params)
if correct_password(params)
set_session
redirect "/users/#{session[:user_id]}"
else
redirect '/login'
end
end
get '/users/:user_id' do |id|
#user = User.find(id)
erb :'users/index' # from this point I want to run my angular app
end
I was looking for a way to tell the ui-router that it should regard that route as the applications root route, by doing url: '/users/:id', but that doesn't work.
Is there way to achieve what I'm looking for?
Thanks in advance
EDIT:
My god, I forgot to put the basic ng-app='myapp' directive somewhere in my html, which explains why my initial state never became active. Having changed that, my initial configuration works perfectly fine.
I'm not sure whether to delete this question or to keep it here for educational purposes.
The defined routes are viable after the #. So the route defined as / will be accessible on /users/:id#/ or /users#/ or even /#/.

html5Mode with base tag does not work on refresh

AngularJS - html5Mode - Cannot GET /login
So I have seen this post and my problem is very similar. I have used base tag to get my relative urls to work. And I have $locationProvider.html5Mode(true); in my application. Everything seems to work fine to keep /#/ urls out of the application, but when the user refreshes the browser it says page not found. The url it is going to is where my router should be pointing to:
$routeProvider
.when('/', {
templateUrl: 'views/coverPage.html',
controller: 'MainCtrl'
})
.when('/coverPage', {
templateUrl: 'views/coverPage.html',
controller: 'MainCtrl'
})
This is just an example of my router page. Again, this works when I link through a button, but when I load the url: http://www.someurl.com/somepath/coverPage it says page not found.
If it works fine, when navigating from a link but get a page not found when you refresh it appears to be a server side issue.
Be sure to acutally load the right angular app from the server at the specified url. You need a kind of wildcard url matching for the server side route. But without knowing more details of your application I can only guess.

AngularJS: how to enable $locationProvider.html5Mode with deeplinking

When enabling the html5Mode in AngularJS via $locationProvider.html5Mode(true), navigation seems to be skewed when you land on a page deeper in the site.
for example:
http://www.site.com
when i navigate to the root, i can click all links in the site, Angular's $routeProvider will take over navigating through the site and loading the correct views.
http://www.site.com/news/archive
but when i navigate to this url (or hit refresh when I'm on a deeplink like the above one...) this navigation is not working as I expect it to.
first of all, our as the Documentation for $locationProvider.html5Mode specifies, we catch all urls on the server, similar to the otherwise route in angular, and return the same html as the root domain. But if I then check the $location object from within the run function of angular, it tells me that http://www.site.com is my host and that /archive is my path. the $routeProvider arrives in the .otherwise() clause, since i only have /news/archive as a valid route. and the app does weird stuff.
Maybe the rewriting on the server needs to be done differently, or I need to specify stuff in angular, but currently i'm clueless as to why angular see's the path without the /news segment included.
example main.js:
// Create an application module
var App = angular.module('App', []);
App.config(['$routeProvider', '$locationProvider', function AppConfig($routeProvider, $locationProvider) {
$routeProvider
.when(
'/', {
redirectTo: '/home'
})
.when('/home', {
templateUrl: 'templates/home.html'
})
.when('/login', {
templateUrl: 'templates/login.html'
})
.when('/news', {
templateUrl: 'templates/news.html'
})
.when('/news/archive', {
templateUrl: 'templates/newsarchive.html'
})
// removed other routes ... *snip
.otherwise({
redirectTo: '/home'
}
);
// enable html5Mode for pushstate ('#'-less URLs)
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
}]);
// Initialize the application
App.run(['$location', function AppRun($location) {
debugger; // -->> here i debug the $location object to see what angular see's as URL
}]);
Edit
as per request, more details on the server side:
the server side is organised by the routing of zend framework, and it handles it's own routes (for serving data to the frontend on specific /api urls, and at the end, there is a catch-all route if no specific other route is bound, it serves the same html as the root-route.
so it basically serves the homepage html on that deeplinked route.
Update 2
after looking into the problem we noticed this routing works fine as it is, on Angular 1.0.7 stable, but shows the above described behaviour in the Angular 1.1.5 unstable.
I've checked the change-logs but haven't found anything useful so far, I guess we can either submit it as a bug, or unwanted behaviour linked to a certain change they did, or just wait and see if it get's fixed in the later to be released stable version.
Found out that there's no bug there.
Just add:
<base href="/" />
to your <head />.
This was the best solution I found after more time than I care to admit. Basically, add target="_self" to each link that you need to insure a page reload.
http://blog.panjiesw.com/posts/2013/09/angularjs-normal-links-with-html5mode/
This problem was due to the use of AngularJS 1.1.5 (which was unstable, and obviously had some bug or different implementation of the routing than it was in 1.0.7)
turning it back to 1.0.7 solved the problem instantly.
have tried the 1.2.0rc1 version, but have not finished testing as I had to rewrite some of the router functionality since they took it out of the core.
anyway, this problem is fixed when using AngularJS vs 1.0.7.
Configure AngularJS
$location / switching between html5 and hashbang mode / link rewriting
Configure your server:
https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#wiki-how-to-configure-your-server-to-work-with-html5mode
My problem solved with these :
1- Add this to your head :
<base href="/" />
2- Use this in app.config
$locationProvider.html5Mode(true);

Resources