25

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 as aBouT

Cheers

4

4 Answers 4

30

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I find this approach much better than the approved answer since it won't rewrite the url
15

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.

4 Comments

As of version 0.2.12 and later, this can be accomplished with a single line without rewriting the URLs. See @kmkemp's answer.
Ageed 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
@Axel - StateChangeSuccess won't fire twice. It only fires once. Also mentions this in the comment in the code
@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...
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.

4 Comments

I'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.
And by the way - you would want to use $window vs window to keep it all 'within' angualr.
@Darren Yea I only saw the link in the comment after I posted. I'd go with rule()
ah ok :) I supposed I should put an answer in here to help others :) - i'll do that now...
-2

According to official wiki,

https://github.com/angular-ui/ui-router/wiki/URL-Routing

Darren's answer looks right:

app.config(function ($urlRouterProvider) {
  // Here's an example of how you might allow case insensitive urls
   $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
});}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.