angular-ui / ui-router

The de-facto solution to flexible routing with nested views in AngularJS
http://ui-router.github.io/
MIT License
13.54k stars 3k forks source link

Trailing slash not working with optional parameter #1866

Closed JobaDiniz closed 9 years ago

JobaDiniz commented 9 years ago

The how to make a trailing slash optional mention using $urlMatcherFactoryProvider.strictMode(false), which I do, however, if I have an optional parameter in the url, then this doesn't work.

$urlMatcherFactoryProvider.strictMode(false) works for:

$stateProvider.state('main.myTv', {
            url: '/myTv',
            templateUrl: 'my-tv/myTv.html',
            controller: 'MyTvController'
        });

$urlMatcherFactoryProvider.strictMode(false) does not work for:

$stateProvider.state('main.tv', {
            url: '/tv/{channelPid}??date&orderBy&view',
            templateUrl: 'tv/tv.html',
            controller: 'TvController'
        });

All following routes should match: :x: /tv :white_check_mark: /tv/ :white_check_mark: /tv/pid123 :white_check_mark: /tv/pid123?orderBy=date

ghost commented 9 years ago

http://plnkr.co/edit/VbhITL47ypgVvztRXz1b?p=preview (for example above)

eddiemonge commented 9 years ago

Have you tried squash: true? http://plnkr.co/edit/e11qr1f9dd0Kt3MjPKTE?p=preview

ncapito commented 9 years ago

@eddiemonge I'm still having issues with this. I simplified the plunkr so are now just 2 states home & tv. If you try to hit #/tv it wont route.

  $urlMatcherFactoryProvider.strictMode(false);

  $stateProvider
    .state('home', {
      url: '/',
      template: '<h3>Home state</h3>'
    })
    .state('tv', {
      url: '/tv/',
      template: '<h3>{{ location }}</h3>',
      controller: function($scope, $location) {
        $scope.location = window.location.href ;

      }
    });
    <a href="#/tv">/tv</a> (fails to route)<br>
    <a href="#/tv/">/tv/</a><br>
rgolea commented 9 years ago

I think that is because it's trying to define another routhe with an empty string. You should always define url: "/tv" and not "/tv/". The strict mode is applied to users, it's not a way to let you get away with mistakes.

Sent from my iPhone

On 21 Sep 2015, at 13:48, Nick notifications@github.com wrote:

@eddiemonge I'm still having issues with this. I simplified the plunkr so are now just 2 states home & tv. If you try to hit /tv it wont route.

$urlMatcherFactoryProvider.strictMode(false);

$stateProvider .state('home', { url: '/', template: '

Home state

' }) .state('tv', { url: '/tv/', template: '

{{ location }}

', controller: function($scope, $location) { $scope.location = window.location.href ;

  }
});
<a href="#/tv">/tv</a> (fails to route)<br>
<a href="#/tv/">/tv/</a><br>

— Reply to this email directly or view it on GitHub.

eddiemonge commented 8 years ago

^^ And I don't see optional parameters in there nor squash.

NeoGenet1c commented 6 years ago

Related and might help anyone else who encounters this.

Make sure you do turn off the strictMode before you'll add your states through the state() method. It looks like the method is dependant on the strictMode flag.

        // Make trailing slash optional
        $urlMatcherFactoryProvider.strictMode( false );
SamanthaAdrichem commented 1 year ago

@NeoGenet1c thank you! ** took me forever to figure out that it works like this. That strictmode is only applied to states that are not declared yet!

We used to do

AppModule

    imports: [
        submodule
        routerModule.forRoot(config -> with strictmode to false)
    ]

and then in submodule

    imports: [
        routerModule.forChild(statesOfSubModule)
    ]

and it doesn't matter in what order you do the imports, Angular first loads the submodule before the config of routermodule is executed causing all states to be defined already, causing strict mode not to work.

So we removed the state declarations in the submodule and moved them back to the main app module (less clean but ok :() and now it works

AppModule

    imports: [
        routerModule.forRoot(config -> with strictmode to false, allStates)
    ]

and it used to work when we ran hybrid because the angularJs version works differently. soo many issues when going away from hybrid what used to work just stops working.. :(