3

I was working on migration of my Angularjs code from ng-router to UI-Router. In my ng-router I have optional parameters however I realized that same easy way to support optional parameter is not supported in ui-router. Following is my routes from my existing ng-router module.

//Define routes for view  using ng-router
$routeProvider.
        when('/my-app/home/:userid?', {
            templateUrl: '/templates/partials/home/HomeView.html',
            controller: 'HomeViewController'
        })                   
        .when('/my-app/:productKey/:userid?', {
            templateUrl: '/templates/partials/productpage/ProductPageView.html',
            controller: 'ProductViewController'
        })
        .otherwise({redirectTo: '/my-app/home'});

Note: If you see ":userid" parameter is very smoothly implemented here as optional.

I tried following in ui-router however same is not working. I have gone through many post and it was suggested to duplicate the routes. I really don't want to duplicate as it will make code dirty.

//Set the default route

$urlRouterProvider.otherwise('/my-app/home');
//Define routes for view   (Please make sure the most matched pattern is define at top)
$stateProvider
        .state('viewallcards', {
            url: '/my-app/home/:userid',
            templateUrl: '/templates/partials/home/HomeView.html',
            controller: 'HomeViewController'
        })
        .state('productpage', {
            url: '/my-app/:productKey/:userid',
            templateUrl: '/templates/partials/productpage/ProductPageView.html',
            controller: 'ProductViewController'
        });

Here /my-app/home/ works however /my-app/home doesn't work. How to make it without trailing slash as well?

Also following post on same issue has surprised to me to know that this is not supported in ui-router. Is it still valid? Please help.

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
joy
  • 3,669
  • 7
  • 38
  • 73
  • I don't think ui-router's parameterized URLs need question marks in the case of an optional parameter. – Jon Edwards Jun 08 '15 at 23:29
  • it doesn't work with or without ?. If i remove ? then trailing slash doesn't work. – joy Jun 08 '15 at 23:31
  • When I've used ui-router, I've used the curly brace form for the variables. I couldn't get the colon form to work. Maybe try {userid}? instead of :userid?, FWIW. – Jon Edwards Jun 08 '15 at 23:34
  • Not working for me :-( – joy Jun 08 '15 at 23:54
  • Are you getting an error? Is it loading the page at all and not passing the parameters? – Jon Edwards Jun 08 '15 at 23:56
  • with {} also it behaves same, i.e. it works only with trailing slash.....if i remove trailing slash then it is not able to find the route. – joy Jun 09 '15 at 00:00

2 Answers2

9

There is a working example

We can use params : {} object to define the userid exactly as we need (i.e. ready to be omitted).

Check more details about params here:

Angular ui router passing data between states without URL

  $stateProvider
    .state('viewallcards', {
      url: '/my-app/home/:userid',
      params: { 
        userid: {squash: true, value: null }, // this will make both links below working:
        //         #/my-app/home
        //         #/my-app/home/
      },
      ...
    })
    .state('productpage', {
      url: '/my-app/:productKey/:userid',
      ...
    })

Check it in action here

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • 1
    Thanks. I will try this, I am sure this should work. – joy Jun 09 '15 at 21:50
  • The docs recommendation to set $urlMatcherFactoryProvider.strictMode(false) did NOT work, whereas this did. Thanks. – Jay Jan 13 '17 at 18:32
0

By default, UI Router is in "strict mode" - where it differentiates between routes with a trailing slash and without. You can turn this off by disabling this mode:

How can I have my routes be activated when the url contains either a trailing slash or not?

Set strictMode to false in your config block:

$urlMatcherFactoryProvider.strictMode(false)

For older version of ui-router, add this snippet to your module's config function. It creates a rule on $urlRouterProvider that maps all urls that are missing a trailing slash to the same url but with the trailing slash appended.

Using this, it's best to define your optional parameters as URL parameters in the style of home?userid=foo, and set stuff that you always expect to see in the URL.

From the UI-Router's Wiki.

Community
  • 1
  • 1
nitsua
  • 763
  • 8
  • 20
  • Which option will be better? Using {squash: true, value: null } or $urlMatcherFactoryProvider.strictMode(false)? – joy Mar 22 '16 at 22:05
  • I think for your case, squash: true is better as it better allows you to define an Optional parameter that is part of the URL. I've used strictMode(false) to define that I want the route to contain a trailing slash or not where I've used URL parameters and it's worked really well for me. – nitsua Mar 24 '16 at 14:04