382

I need to pass and receive two parameters to the state I want to transit to using ui-sref of ui-router.

Something like using the link below for transitioning the state to home with foo and bar parameters:

<a ui-sref="home({foo: 'fooVal', bar: 'barVal'})">Go to home state with foo and bar parameters </a> 

Receiving foo and bar values in a controller:

app.controller('SomeController', function($scope, $stateParam) { //.. var foo = $stateParam.foo; //getting fooVal var bar = $stateParam.bar; //getting barVal //.. }); 

I get undefined for $stateParam in the controller.

Could somebody help me understand how to get it done?

Edit:

.state('home', { url: '/', views: { '': { templateUrl: 'home.html', controller: 'MainRootCtrl' }, 'A@home': { templateUrl: 'a.html', controller: 'MainCtrl' }, 'B@home': { templateUrl: 'b.html', controller: 'SomeController' } } }); 
4
  • 5
    You need to have them set up in your routes as well. ex:- url:'.../home/:foo/:bar Commented Sep 3, 2014 at 14:51
  • @PSL: Could you just give a small example here? Thanks. Commented Sep 3, 2014 at 14:55
  • @PSL: Thanks PSL, is there any other way I could have those parameters with their values in a controller? Commented Sep 3, 2014 at 15:01
  • 1
    Do '/:foo/:bar': { in your blank route or you can set up as querystring as well. Commented Sep 3, 2014 at 15:01

3 Answers 3

546

I've created an example to show how to. Updated state definition would be:

 $stateProvider .state('home', { url: '/:foo?bar', views: { '': { templateUrl: 'tpl.home.html', controller: 'MainRootCtrl' }, ... } 

And this would be the controller:

.controller('MainRootCtrl', function($scope, $state, $stateParams) { //.. var foo = $stateParams.foo; //getting fooVal var bar = $stateParams.bar; //getting barVal //.. $scope.state = $state.current $scope.params = $stateParams; }) 

What we can see is that the state home now has url defined as:

url: '/:foo?bar', 

which means, that the params in url are expected as

/fooVal?bar=barValue 

These two links will correctly pass arguments into the controller:

<a ui-sref="home({foo: 'fooVal1', bar: 'barVal1'})"> <a ui-sref="home({foo: 'fooVal2', bar: 'barVal2'})"> 

Also, the controller does consume $stateParams instead of $stateParam.

Link to doc:

You can check it here

params : {}

There is also new, more granular setting params : {}. As we've already seen, we can declare parameters as part of url. But with params : {} configuration - we can extend this definition or even introduce paramters which are not part of the url:

.state('other', { url: '/other/:foo?bar', params: { // here we define default value for foo // we also set squash to false, to force injecting // even the default value into url foo: { value: 'defaultValue', squash: false, }, // this parameter is now array // we can pass more items, and expect them as [] bar : { array : true, }, // this param is not part of url // it could be passed with $state.go or ui-sref hiddenParam: 'YES', }, ... 

Settings available for params are described in the documentation of the $stateProvider

Below is just an extract

  • value - {object|function=}: specifies the default value for this parameter. This implicitly sets this parameter as optional...
  • array - {boolean=}: (default: false) If true, the param value will be treated as an array of values.
  • squash - {bool|string=}: squash configures how a default parameter value is represented in the URL when the current parameter value is the same as the default value.

We can call these params this way:

// hidden param cannot be passed via url <a href="#/other/fooVal?bar=1&amp;bar=2"> // default foo is skipped <a ui-sref="other({bar: [4,5]})"> 

Check it in action here

Sign up to request clarification or add additional context in comments.

3 Comments

Great answer but what if I want to do something like this - <a ui-sref="profile.dashboard({aintUserId : [{{ibusUser.icdoUser.idoUser.userId}}] })"> this does not work. How can I get it to work?
@Radim, can you take a look at stackoverflow.com/questions/41429784/… and help me a bit
You can also have a url like this: url: "/:id?foo&bar"
111

You don't necessarily need to have the parameters inside the URL.

For instance, with:

$stateProvider .state('home', { url: '/', views: { '': { templateUrl: 'home.html', controller: 'MainRootCtrl' }, }, params: { foo: null, bar: null } }) 

You will be able to send parameters to the state, using either:

$state.go('home', {foo: true, bar: 1}); // or <a ui-sref="home({foo: true, bar: 1})">Go!</a> 

Of course, if you reload the page once on the home state, you will loose the state parameters, as they are not stored anywhere.

A full description of this behavior is documented here, under the params row in the state(name, stateConfig) section.

Comments

31

You simply misspelled $stateParam, it should be $stateParams (with an s). That's why you get undefined ;)

1 Comment

Generally this should go as a comment in the question. But anyway +1 for the efforts taken in reading the question and understanding the problem :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.