32

Can I set a default value of a parameter of a route in AngularJS? Is there a way to have /products/123 and /products/ handled by the same route ?

I'm looking to refactor my existing code, which looks like:

myModule.config(['$routeProvider', function($routeProvider) {
    $routeProvider.
     when('/products/', {templateUrl: 'products.html', controller: ProductsCtrl}).            
     when('/products/:productId', {templateUrl: 'products.html', controller: ProductsCtrl})
}]);


function ProductsCtrl($scope, $routeParams) {
    $scope.productId = typeof($routeParams.productId) == "undefined" ? 123 : $routeParams.productId;
}

It works, but it's not very elegant. Is there a better way ?

6
  • Not familiar with angularJS, but what about var param ={templateUrl: 'products.html', controller: ProductsCtrl}; $routeProvider.when('/products/', param).when('/products/:productId', param)? Commented Sep 21, 2012 at 6:16
  • 3
    You can simplify your controller code a bit with: $scope.productId = $routeParams.productId || 123; Commented Sep 21, 2012 at 18:37
  • @Gloopy this of course works if productId == 0 is not a valid id Commented Sep 22, 2012 at 21:11
  • Thanks guys, that does make it a bit shorter. Just the issue of whether default parameters are possible to go... ;) Commented Sep 25, 2012 at 4:15
  • Do not forget ProductsCtrl.$inject = ['$scope', '$routeParams'];. Commented Oct 9, 2012 at 19:20

5 Answers 5

35

I recognize that this question is old, but still: Why don't you just redirect the "empty" URL to one containing the default productId?

myModule.config(['$routeProvider', function($routeProvider) {
    $routeProvider.
     when('/products/', {redirectTo: '/products/123'}).
     when('/products/:productId', {templateUrl: 'products.html', controller: ProductsCtrl})
}]);
Sign up to request clarification or add additional context in comments.

1 Comment

Method Overloading FTW!
24

AngularJS does not allow default values for route parameters.

But routes (in AngularJS) should not have default parameters.

Resources could have default parameters.

In AngularJS if you want a route with an optional parameter, these are actually two different routes.

Why?

  • Routes should be simple

  • Routes does not allow regular expressions matching for parameters

  • Routes are not something which exposes an API to work in your application (unlike Resources do). Routes are just configuration which connects a URL with a template and a controller. Thus having more routes is better:

    • It is clear which route maps to which url.

    • It is more verbose, but simpler to read. Having more complex routes would create a steeper learning curve where AngularJS does not need one.

Unlike server-side frameworks which have routes

  • AngularJS routes do not have names.
  • You do not build URLs from the defined routes.
  • You do not have logic (a.k.a functions) in the routes definitions.

Simpler routes = more lines to define them = less headaches working with them.

NOTE: Please keep in mind the question and this answer are for an old version of AngularJS (1.0 I think) pre-dating the new routes/resources implementation.

6 Comments

Though this may be the correct answer I don't see any strong argument here that should prevent AngularJS from having default params or better route matching. Repeating identical code is always a problem for maintenance.
@edA-qamort-ora-y My point is that in the current state of AngularJS routes (which is probably going to change) routes should be kept simple.
Though this conversation is a bit dated I have heard that in the Angular 2 release there will be support for pattern matching for routes, this may also include some way to do optional or defaulted parameters.
@shaunhusain yes, this is most probably going to change. But the new AngularJS routes and all change a lot of the pre-conditions for the question and the answer.
Optional routes are now available right stackoverflow.com/questions/17510962/…
|
6

I had a similar requirement. What i did was to create a function to resolve. Something like below

myModule.config(['$routeProvider', function($routeProvider) {
$routeProvider.
 when('/products/', resolveProduct()).            
 when('/products/:productId', resolveProduct())
}]);


function ProductsCtrl($scope, $routeParams) {
$scope.productId = $routeParams.productId;
}

function resolveProduct() {
   var routeConfig = {
      templateUrl: 'products.html', 
      controller: ProductsCtrl,
      resolve: {
         productId: ['$route', function($route){
            var params = $route.current.params;
            params.productId =  params.productId || 123;
         }]
      }
   }

   return routeConfig;
}

Comments

3

With url: "/view/:id/:status?", You can indicate an optional parameter.

Just thought someone may need it.

Comments

2

Not sure if this question is specific to $routeProvider but in $stateProvider, you can achieve this by

myApp.config(function($stateProvider) {

    $stateProvider
        .state('products', {
            url: '/:productId',
            templateUrl: "/dashboard/products.html",
            controller: 'ProductController',
            params: {
                productId: {
                  value: "defaultValue",
                  squash: true // or enable this instead to squash `productId` when empty
                } 
            }
        });
});

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.