Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`ui-router` $stateParams vs. $state.params

People also ask

What is state params?

$stateParams is a service that captures URL-based parameters, and we can use these parameters to display information according to the state. Let's create an example with two states, understand how states work, and use $stateparams to store parameters. We will use $stateProvider to create a state.

What is UI sref in AngularJS?

Angular UI-Router is a module that helps us create single-page applications. It provides an abstraction between the application and the browser by managing all of the routes in our application. It also helps make changes to our application in a more efficient way.

What is state go in AngularJS?

The $state.go is an AngularJS directive that tells the view to update its URL to reflect the current state of the application. This directive is used to change the URL without navigating away from the current page.


The documentation reiterates your findings here: https://github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service

If my memory serves, $stateParams was introduced later than the original $state.params, and seems to be a simple helper injector to avoid continuously writing $state.params.

I doubt there are any best practice guidelines, but context wins out for me. If you simply want access to the params received into the url, then use $stateParams. If you want to know something more complex about the state itself, use $state.


Another reason to use $state.params is for non-URL based state, which (to my mind) is woefully underdocumented and very powerful.

I just discovered this while googling about how to pass state without having to expose it in the URL and answered a question elsewhere on SO.

Basically, it allows this sort of syntax:

<a ui-sref="toState(thingy)" class="list-group-item" ng-repeat="thingy in thingies">{{ thingy.referer }}</a>

EDIT: This answer is correct for version 0.2.10. As @Alexander Vasilyev pointed out it doesn't work in version 0.2.14.

Another reason to use $state.params is when you need to extract query parameters like this:

$stateProvider.state('a', {
  url: 'path/:id/:anotherParam/?yetAnotherParam',
  controller: 'ACtrl',
});

module.controller('ACtrl', function($stateParams, $state) {
  $state.params; // has id, anotherParam, and yetAnotherParam
  $stateParams;  // has id and anotherParam
}

There are many differences between these two. But while working practically I have found that using $state.params better. When you use more and more parameters this might be confusing to maintain in $stateParams. where if we use multiple params which are not URL param $state is very useful

 .state('shopping-request', {
      url: '/shopping-request/{cartId}',
      data: {requireLogin: true},
      params : {role: null},
      views: {
        '': {templateUrl: 'views/templates/main.tpl.html', controller: "ShoppingRequestCtrl"},
        'body@shopping-request': {templateUrl: 'views/shops/shopping-request.html'},
        'footer@shopping-request': {templateUrl: 'views/templates/footer.tpl.html'},
        'header@shopping-request': {templateUrl: 'views/templates/header.tpl.html'}
      }
    })

I have a root state which resolves sth. Passing $state as a resolve parameter won't guarantee the availability for $state.params. But using $stateParams will.

var rootState = {
    name: 'root',
    url: '/:stubCompanyId',
    abstract: true,
    ...
};

// case 1:
rootState.resolve = {
    authInit: ['AuthenticationService', '$state', function (AuthenticationService, $state) {
        console.log('rootState.resolve', $state.params);
        return AuthenticationService.init($state.params);
    }]
};
// output:
// rootState.resolve Object {}

// case 2:
rootState.resolve = {
    authInit: ['AuthenticationService', '$stateParams', function (AuthenticationService, $stateParams) {
        console.log('rootState.resolve', $stateParams);
        return AuthenticationService.init($stateParams);
    }]
};
// output:
// rootState.resolve Object {stubCompanyId:...}

Using "angular": "~1.4.0", "angular-ui-router": "~0.2.15"


An interesting observation I made while passing previous state params from one route to another is that $stateParams gets hoisted and overwrites the previous route's state params that were passed with the current state params, but using $state.params doesn't.

When using $stateParams:

var stateParams        = {};
stateParams.nextParams = $stateParams; //{item_id:123}
stateParams.next       = $state.current.name;

$state.go('app.login', stateParams);
//$stateParams.nextParams on app.login is now:
//{next:'app.details', nextParams:{next:'app.details'}}

When using $state.params:

var stateParams        = {};
stateParams.nextParams = $state.params; //{item_id:123}
stateParams.next       = $state.current.name;

$state.go('app.login', stateParams);
//$stateParams.nextParams on app.login is now:
//{next:'app.details', nextParams:{item_id:123}}