Case insensitivity with angularjs ui-router
Solution 1
Following the link in the comments to the original question, i was able to get the answer I needed.
Before my $stateProvider.state(......)
routes I now have this piece of code:
$urlRouterProvider.rule(function ($injector, $location) {
//what this function returns will be set as the $location.url
var path = $location.path(), normalized = path.toLowerCase();
if (path != normalized) {
//instead of returning a new url string, I'll just change the $location.path directly so I don't have to worry about constructing a new url string and so a new state change is not triggered
$location.replace().path(normalized);
}
// because we've returned nothing, no state change occurs
});
Essentially it will toLowerCase()
a url that isn't all lowercase already.
Once done, it replaces the url rather than redirects. Then carries on with matching a state.
Solution 2
You can now configure ui-router to be case insensitive directly. Here is how you can use it:
angular.module('main', ['ui.router']);
angular.module('main').config(['$urlMatcherFactoryProvider', '$stateProvider', '$urlRouterProvider',
function($urlMatcherFactory, $stateProvider, $urlRouter) {
$urlMatcherFactory.caseInsensitive(true);
$urlMatcherFactory.strictMode(false);
$stateProvider.state('foo', {
url: '/foo',
template: '<b>The Foo View</b>'
});
$stateProvider.state('bar', {
url: '/bar',
template: '<b>The Bar View</b>'
});
$stateProvider.state('nomatch', {
url: '/nomatch',
template: '<b>No match found View</b>'
});
$urlRouter.otherwise('/nomatch');
}
]);
In the latest release (0.2.11), this is broken. A fix has been pushed already that can be seen at Github. So, currently, the best solution is to clone ui-router and build the head of master manually. Alternatively, you can just alter the source manually until the next release comes.
UPDATE (11/18/2014):
A release has now been made that incorporates the fix from above so that you no longer have to pull source and build manually. You can view the release on Github or just get the latest build.
Solution 3
You shouldn't change how ui-route handles URL matching to accept case insensitive URLs (that will have unexpected problems), but you can attempt to correct URLs for the user automatically when the routes fail.
When ui-route can not match a URL to a route it triggers the otherWise()
callback. I'll show you have to redirect using this callback.
The following makes the assumption that all URLs for your app should be in lower case.
var stateHandler = function($urlRouterProvider)
{
$urlRouterProvider.otherwise(function($injector, $location)
{
var url = $location.absUrl();
var redirect = url.toLowerCase();
if(url == redirect)
{
return;
}
$window.location = redirect;
});
};
YourAngularApp.config(['$urlRouterProvider',stateHandler]);
If you need more control, then use a regex to select which URLs need rewriting.
Related videos on Youtube
Darren Wainwright
Updated on June 04, 2022Comments
-
Darren Wainwright almost 2 years
I'm building a new angularJS app, based from the AngularJS SPA Visual studio template (http://visualstudiogallery.msdn.microsoft.com/5af151b2-9ed2-4809-bfe8-27566bfe7d83)
this uses ui-router (https://github.com/angular-ui/ui-router) for its routing.
however, it seems to be case sensitive.
Any idea how I would instruct angular/ui-router to ignore the case of the
url
parameter?case sensitivity doesn't matter while in the app, though should a user type a url to enter the application at a specific page, we need to ensure that
about
is also the same asaBouT
Cheers
-
Sergiu Paraschiv about 10 yearsCheck this out: github.com/angular-ui/ui-router/wiki/…
-
shaunhusain about 10 yearsThink you could post this as an answer Sergiu
-
Sergiu Paraschiv about 10 yearsI think the answer here best describes the solution: stackoverflow.com/questions/14994324/… It's not a clear duplicate though.
-
Darren Wainwright about 10 yearsmany thanks guys. new with angular so clearly missed these :)
-
-
Darren Wainwright over 9 yearsI'm not sure how this really differs from the method I ended up using (via the link in the question comments -
$urlRouterProvider.rule()
- other than the rule will apply any changes before attempting to find a route. Where as your solution is first checking all known routes, then changing the url and then redirecting. -
Darren Wainwright over 9 yearsAnd by the way - you would want to use
$window
vswindow
to keep it all 'within' angualr. -
Reactgular over 9 years@Darren Yea I only saw the link in the comment after I posted. I'd go with
rule()
-
Darren Wainwright over 9 yearsah ok :) I supposed I should put an answer in here to help others :) - i'll do that now...
-
sebas2day over 9 yearsI find this approach much better than the approved answer since it won't rewrite the url
-
Matt DeKrey about 9 yearsAs of version 0.2.12 and later, this can be accomplished with a single line without rewriting the URLs. See @kmkemp's answer.
-
Axel over 8 yearsAgeed with@MattDeKrey doing this will result in having $stateChangeSuccess trigger twice because of the rewriting of the url. Just put $urlMatcherFactory.caseInsensitive(true); in the run() function
-
Darren Wainwright over 8 years@Axel - StateChangeSuccess won't fire twice. It only fires once. Also mentions this in the comment in the code
-
Axel over 8 years@Darren well, it happened to me just today, with the above code, using go(state) triggered twice stateChangeSuccess one with lowercase toParam and one with uppercase toParam....Commenting the line $location.replace().path(normalized); stopped this beviours...