Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling trailing slashes in angularUI router

It's been hours since I started working on this problem and I can't seem to get my head around the solution.

I have an app that may result in users actually typing in the URL. In such cases it is not hard to believe that user might enter a trailing slash. For example,

www.example.com/users/2 and www.example.com/edit/company/123

should be treated the same as

www.example.com/users/2/ and www.example.com/edit/company/123/

This only needs to done for handling URL routing on the client side. I am not interested in handling trailing slashes in resource/API calls. I am only interested in handling trailing slashed in the browser.

So I researched and found not many answers on the net. Most of them led me to the FAQ section of angular-ui router.

https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions

Here they tell us to write a rule, which is what I want to do, but it doesn't seem to be working, or maybe I am doing it wrong.

Here's the plunkr where I have added my code.

http://plnkr.co/edit/fD9q7L?p=preview

I have added this to my config, the rest of the code is pretty much the basic stuff.

$urlRouterProvider.rule(function($injector, $location) {
  //if last charcter is a slash, return the same url without the slash
  if($location.$$url[length-1] === '/') {
    return $location.$$url.substr(0,$location.$$url.length - 2);
  } else {
    //if the last char is not a trailing slash, do nothing
    return $location.$$url;
  }
});

Basically, I want to make the trailing slash optional, ie it's presence or absence on the address bar should have no effect on the state loaded.

like image 972
SLearner Avatar asked Jun 26 '14 00:06

SLearner


4 Answers

There is a link to working plunker

And this is the updated rule definition:

  $urlRouterProvider.rule(function($injector, $location) {

    var path = $location.path();
    var hasTrailingSlash = path[path.length-1] === '/';

    if(hasTrailingSlash) {

      //if last charcter is a slash, return the same url without the slash  
      var newPath = path.substr(0, path.length - 1); 
      return newPath; 
    } 

  });

And these links will now work properly:

  <ul class="nav">
    <li><a ui-sref="route1">Route 1</a></li>
    <li><a ui-sref="route2">Route 2</a></li>
    <li><a href="#/route1/">#/route1/</a></li>
    <li><a href="#/route2/">#/route2/</a></li>
    <li><a href="#/route1" >#/route1</a></li>
    <li><a href="#/route2" >#/route2</a></li>
  </ul>

The magic could be defined like this: do return changed value if there is a change... otherwise do nothing... see example

like image 168
Radim Köhler Avatar answered Nov 09 '22 11:11

Radim Köhler


As of ui-router version 0.2.11 you can do this:

$urlMatcherFactoryProvider.strictMode(false);

This will treat URLs with and without trailing slashes identically.

like image 33
larandev Avatar answered Nov 09 '22 09:11

larandev


I don't have enough rep for a comment so making an answer :-

$urlMatcherFactoryProvider.strictMode(false);

Needs to be before the $stateProvider.state part.

like image 7
openJT Avatar answered Nov 09 '22 09:11

openJT


urlMatcherFactoryProvider is deprecated for v1.x of angular-ui-router.

Use urlService.config.strictMode (ng1, ng2) instead.

It still needs to be before $stateProvider.state().

myApp.config(function($stateProvider, $urlServiceProvider) {
  var homeState = {
    name: 'home',
    url: '/home',
    component: 'xyHome'
  };

  $urlServiceProvider.config.strictMode(false);

  $stateProvider.state(homeState);

});

like image 3
tbmpls Avatar answered Nov 09 '22 09:11

tbmpls