$routeProvider.when('/', ...) has no effect, when html5 mode is on - angularjs

Solution to the problem: url you write in base tag should have a trailing slash.
I have the following routes configuration, but template is not requested, if html5 mode is on. No errors, no attempts to get the resource from the server.
Neither changing base url, nor setting prefix with hasPrefix('!') has no effect on this behavior
angular
.module('beneficiaryBanks')
.config(configRoutes);
configRoutes.$inject = ['$routeProvider','$locationProvider'];
function configRoutes($routeProvider, $locationProvider) {
$routeProvider
.when('/',
{
controller: 'beneficiaryBanksListController',
controllerAs: 'listVM',
templateUrl: 'BeneficiaryBanksList.cshtml'
});
$locationProvider.html5Mode(true);
}
It looks like angular does not match current url with '/'.
update 1
Debugging shows that for url http://localhost:8080/APS/Home/BeneficiaryBanksModule and base address APS/Home/BeneficiaryBanksModule angular sees route as /BeneficiaryBanksModule which does not match with /, whereas route becomes just a / when html5 mode is disabled.

As I could see here, there are some configurations that you may have to do in order to achieve this combination of AngularJS and IIS Express with html5 mode activated.
I don't know if you read this article, but there are a few tips to make it work.

That's because your request is handled by server itself, but not by your angular app.
Try to read some articles about how to setup your server to work with html5 mode:
https://dzone.com/articles/fixing-html5mode-and-angular
http://www.thinkovator.com/blog/post/angularjs-html5-mode-and-iis-rewrite/
Hope, it will help.

The problem was in base tag. If it does not end with slash / angular treats last part as a file name and drops it.
That's why I saw /BeneficiaryBanksModule instead of /

Related

Angular JS UI-Route Navigation

I'm trying to make a simple routing using UI-Route in Angular,but when I'm typing url in browser with # like this http://localhost:8080/#/stateone it adds some weird symbols to it like this http://localhost:8080/#!#%2Fstateone. Can anybody explain me what`s wrong with that?
Here`s my code in app.js file :
angular
.module('myApp', ["ngMaterial", "ui.router"])
.config(function($mdThemingProvider, $stateProvider) {
$mdThemingProvider.theme('default')
.primaryPalette('teal')
.accentPalette('orange');
$stateProvider
.state('stateone' , {
url: '/stateone',
template: '<h1>State One</h1>'
})
.state('statetwo', {
url: '/statetwo',
template: '<h1>State Two</h1>'
});
});
Template`s file code:
<ui-view></ui-view>
You can encode your urls in AngularJS and avoid the hash-bang from your overall app by enabling html5mode mode by adding this simple line in your config block of app.js
$locationProvider.html5Mode(true);
Reference link: AngularJS: how to enable $locationProvider.html5Mode with deeplinking
This problem could appear with the migration from version 1.5 to 1.6...
One of the most notable changes are:
Changing the default $location hash-prefix to '!', as the previous empty string default was unconventional and confusing.
the default hash-prefix used for $location hash-bang URLs has changed
from the empty string ('') to the bang ('!'). If your application does
not use HTML5 mode or is being run on browsers that do not support
HTML5 mode, and you have not specified your own hash-prefix then
client side URLs will now contain a ! prefix. For example, rather than
mydomain.com/#/a/b/c the URL will become mydomain.com/#!/a/b/c.
If you actually want to have no hash-prefix, then you can restore the previous behavior by adding a configuration block to you application:
appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);
Details

ui routing without urlRouterProvider.otherwise

Routing doesn't occur if I don't include $urlRouterProvider.otherwise('/'); in the config.
my go app engine setting with gorilla is
r := mux.NewRouter()
r.HandleFunc(/admin, handleAdmin)
and angularjs config is;
angular.module('admin')
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider.state('home', {
url: '/',
templateUrl: '/admin/index.html',
controller: 'AdminController as admin'
});
//$urlRouterProvider.otherwise('/');
})
when I don't call $urlRouterProvider.othwerwise line, and I open http://localhost:8080/admin I expect to see admin/index.html, but I don't. I see it only if I navigate to http://localhost:8080/admin#/ manually.
But if I add $urlRouterProvider.othwerwise option and go to http://localhost:8080/admin it redirects automatically to http://localhost:8080/admin#/
I don't think this is usual way to do it because I may want "otherwise" to route to a custom 404 page. What point do I miss?
By default, Angular adds the hashPrefix in front of urls. So when you navigate to http://localhost:8080/admin , You don't see index.html since you have not yet visited the url as defined in the angular's ui-router. You will have to navigate to http://localhost:8080/admin/#/ to actuall be in the / state of your application.
It is the same reason that your app doesn't work without the .otherwise(), since then it automatically redirects you to the / state later.
For a possible fix:
Inside your .config function:
// This is in your app module config.
$locationProvider.html5Mode(true);
And in your index.html:
// This is in your index.html head.
<base href="/" />
The problem is not with not having a declared otherwise.
The problem lays on your route. You're specifying the url to be '/', that means the state home is accessible only through http://localhost:8080/admin/ and NOT through http://localhost:8080/admin
What the otherwise does is. When you access the url http://localhost:8080/admin the router try to find a state that matches the url, but don't find it. So it redirects to http://localhost:8080/admin/ which matches with your home state.

prevent angular change hashtag and slash in URL

I try to stop angular to modify the URL format
like from 'mail.google.com/#inbox'
to 'mail.google.com/#/inbox'
the context is I'm developing a Chrome extension, and customer like to use it with Streak in the same time. But sometimes my app will stop 'pipeline' feature of Streak shows up.
And the reason I guess is angular change the URL to different format therefore, stop some function of Streak(maybe)
so, to prevent angular add slash after hash tag,
I use html4 mode in config like
$locationProvider.html5Mode(true);
in fact, it works! but with error message:
$location in HTML5 mode requires a tag to be present!
so I change it the config part to
$locationProvider.html5Mode({
enabled: true,
requireBase: true
});
then error message disappear, but slash will be encode
ex:
"mail.google.com/#pipeline/aaabbbccc..."
become
"mail.google.com/#pipeline%2Faaabbbccc..."
and pipeline not shows up.
then I find method to prevent slash encode from this method
I change config back to
$locationProvider.html5Mode(true);
and add tag to head to index;
as I'm developing a inject script app
I add the html tag by Jquery in content script
$('head').append('<base href="/">');
then situation become weird,it will open new tab and sometimes sign me out of gmail, also pipeline not shows as well.
Furthermore, I find the thing trigger URL change is some directive use $state
Is somebody have idea how to prevent angular modify URL formate change?
or my assumption of reason is wrong?

Use slash inside hash with %2F

I'm having the following routes:
window.m.config( ['$routeProvider',($routeProvider) ->
$routeProvider
.when('/player/:index', {
templateUrl: 'view.html',
controller: 'View'
})
.when('/', {
templateUrl: 'list.html'
controller: 'List'
})
]
)
Some of my players have a / inside their name. So I am decoding it eg, for a player named a/b, the url to that player will be /player/a%2Fb
However, when I do the following, the hash will change when I load my app, so that it becomes /player/a/b.
This makes the page not load for that particular player.
If I put a hash with %2F in a non-angular app, the %2F is not transformed into / so it is not the browser that is inducing the error. However, if I then try to get the hash, I still get /player/a/b , where the encoded slash is === to the other slashes.
How should I handle slashes inside the variable values of my routes ?
You have to add
*
at the end of your route. So in your case:
'/player/:index*'
That should work also with Angullar 2+. Check
Github issue.
I would replace/escape the slashes with underscores when creating the route argument and then re-inserting them in the controller - this way you avoid the differences.
So I just found this on github and wanted to provide a temporary fix, in my application I noticed it would only route on params that were double encoded so for example I used this as a temp work around:
encodeURIComponent(encodeURIComponent("this/string/is/a/param/"))
This seemed to work for me.

Problems with AngularJS $location.path

I am having fun and games with a troublesome AngularJS route, so lets see if I can explain this as well as I can.
APP.JS:
app = angular.module("index", []);
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/booking/damage/:regnumber', {
templateUrl: 'damage',
controller: 'DamageCtrl'
}).
otherwise({
redirectTo: '/'
});
}
]);
app.controller('IndexCtrl', function($scope, $location) {
$scope.regnumber = '';
$scope.progress = function() {
if ($scope.regnumber !== '') {
$location.path('/booking#/damage/' + $scope.regnumber);
} else {
$location.path('/booking#/damage');
}
};
});
My initial page has a path of
http://localhost/windscreens/glass/index#/index
and within this page is a form that via ng-submit="progress() calls the $scope.progress function within my IndexCtrl controller. There is a field in the form of ng-model="regnumber".
So when filling in the input field with lets say "ABC" and clicking on the button, I'd expect the path to become:
http://localhost/windscreens/glass/booking#/damage/ABC
But it becomes
http://localhost/windscreens/glass/index#/booking%23/damage/ABC
Thing is I am still really becoming used to the Angular routing system and haven't quite got it yet. Any advice on this will be appreciated!
Why am I seeing what I am seeing? What have I got wrong here?
The Angular $routeProvider can only change the part of the URL after the hash (#), so when calling $location.path(), you just use a plain URL fragment like you defined in the route for DamageCtrl.
Some explanation
I'm going to simplify a bit here, but hopefully it will help you understand what's going on.
You're making a SPA (single-page app), so the URL you enter in your browser to get into your app doesn't change while you navigate between routes; by default $routingProvider appends #/whatever/route to that base URL. In your case it looks like you have your entry point (ng-app) in a file called /windscreens/glass/index, so all routes will get appended to that.
Because you don't have an /index route defined that we can see, I'm not sure how http://localhost/windscreens/glass/index#/index is working for you. It should send you to http://localhost/windscreens/glass/index#/ because your otherwise route is just /.
Back to the question
If I understand your question correctly, I would make the index file (where ng-app lives) /windscreens/glass/index.html, then you can just enter http://localhost/windscreens/glass/ to get into the app, because the webserver will serve the contents of index.html by default.
At that point, your index page URL would become http://localhost/windscreens/glass/#/, and your /booking/damage/ routes would be http://localhost/windscreens/glass/#/booking/damage/ABC etc. The code to navigate to them would then be
$location.path('/booking/damage');
Angular routing changes the route on the page; it doesn't take you to a new directory or page.
So if index.html contains your Angular app and you have routes for "booking", "reservation", "cancellations", etc. You'll end up with urls that look like:
/glass/index.html#/booking
/glass/index.html#/reservation
/glass/index.html#/cancellations
The route merely appends itself to the index.html.
So, in a sense, your routes are working correctly. The %23 that you see being added is the url encoded # sign.
If you have a second Angular app that is found at /glass/booking and you're trying to forward the user to it, you can use $window.location.hash and $window.location.pathname. For example,
$window.location.hash = "/damage/ABC";
$window.location.pathname = "/windscreens/glass/booking";
should take you to:
/windscreens/glass/booking#/damage/ABC

Resources