Pass data with $state.go


#1

Hey guys,

I have a quick question about routing.
In my app controller I define some routes like so:

$stateProvider.state('login', {
                url: '/login',
                templateUrl: 'templates/login.html',
                controller: 'userController',
                data: {'context':'login'} 

I let people navigate the app if they are not logged in, however at one point I force to login but I want to pass some data to the login page like so:

$state.go('/login',{"experience":experience_id,"context":'login'});

However, when I look at my $state or $stateParams object in my userController I don’t have any of the data I passed in with the $state.go call. Any idea on how to pass that data to my login template??

Thanks in advance


How to Access Data/Variable from One Page to Another
#2

If the params aren’t in the URL, like this:

$stateProvider.state('login', {
  url: '/login/:experience/:context',
  templateUrl: 'templates/login.html',
  controller: 'userController'
});

I think you might need to define a params array in the state, like this:

$stateProvider.state('login', {
  url: '/login',
  params: [
     'experience', 'context'
  ],
  templateUrl: 'templates/login.html',
  controller: 'userController'
});

That should allow you to use your $state.go like you want.

$state.go('login', { experience: experience_id, context: 'login' });

I haven’t tried this so I might be totally wrong.


#3

You’ll need to actually define a route that has the parameters included. In your example, you might want to declare it like so:

.state('login/:experience_id/:context',{
    url:'/login/:experience_id/:context',
//etc

Then call it like

$state.go('login/:experience_id/:context',{experience_id:myIdNumber,context:'login'});

#4

hmm this solution doesn’t really work, because I won’t always pass in an experience id.
I was thinking that when I did $state.go I can simply pass in an extra array that’s not linked to the routing. If you have any experience with native Android, then I guess a comparable concept is passing a bundle.


#5

@compudaze thanks this actually worked!!
The only thing is, I kept getting an error that said: Both params and url specicified in state 'login' . I got rid of the url so now my state looks like this:

state('login', { //url: '/login', templateUrl: 'templates/login.html', controller: 'userController', params: ['context','experience'], data: {'context': 'login','experience_id':':experience_id'}, })

Not sure why I got that error though? Any ideas?
Also, this brings up the issue, that I don’t necessarily always want to pass experience_id. Just if that is set I want to do a different action in my controller. Any ideas on how to make that parameter optional?


#6

ah actually nevermind, the reason my route didn’t work is because I tried going to /login in the url bar, but since I had to remove the url: ‘/login’ it didn’t recognize it.


#7

There are a number of different ui-router patterns you can use depending on your situation:


#8

thanks for the link!


#9

Here “login/:experience_id/:context” goes the state name that is “login”


#10

When I remove the url from my state in this example, I get another weird error: "Uncaught TypeError: Cannot read property ‘insertBefore’ of null "


#11

hmm, not sure I have seen this one before. can you put up a codepen please?


#12

Here is a great reference if you’re struggling on how to pass a parameter to the state. It shows how you define the parameter in the state as well as calling the state using $state.go. This is pretty straight forward as there is 2 parameters to $state.go. Param 0 is the state. Param 1 is the javascript object with the property names being the parameter name as you defined them in the state definition.

http://www.webstein.net/blog/angular-ui-router-pass-parameter-to-go


#13

As soon as I add params: ['something'], it breaks the application:

Uncaught Error: [$injector:modulerr] Failed to instantiate module XXX due to:
TypeError: undefined is not a function
at getArrayMode (http://localhost:8100/lib/ionic/js/ionic.bundle.js:38251:39)
at new Param (http://localhost:8100/lib/ionic/js/ionic.bundle.js:38224:21)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:38857:39
at forEach (http://localhost:8100/lib/ionic/js/ionic.bundle.js:8147:20)
at Object.stateBuilder.ownParams (http://localhost:8100/lib/ionic/js/ionic.bundle.js:38856:7)
at registerState (http://localhost:8100/lib/ionic/js/ionic.bundle.js:38975:72)
at $StateProvider.state (http://localhost:8100/lib/ionic/js/ionic.bundle.js:39460:5)
at $StateProvider.IonicModule.factory.config.$stateProvider.state (http://localhost:8100/lib/ionic/js/ionic.bundle.js:45621:31)
at http://localhost:8100/js/app.js:106:6
at Object.invoke (http://localhost:8100/lib/ionic/js/ionic.bundle.js:11994:17)


#14

I’ve got this same issue, not sure what’s causing it. I can’t get of square one with parameters because adding params to the state declaration instantly breaks the app.

My error is:

Uncaught Error: [$injector:modulerr] Failed to instantiate module westBay due to:
TypeError: id.match is not a function
    at getArrayMode (http://localhost:1337/assets/bower_components/ionic/js/ionic.bundle.js:39257:39)
    at new Param (http://localhost:1337/assets/bower_components/ionic/js/ionic.bundle.js:39230:21)
    at http://localhost:1337/assets/bower_components/ionic/js/ionic.bundle.js:39863:39
    at forEach (http://localhost:1337/assets/bower_components/ionic/js/ionic.bundle.js:9022:20)
    at Object.stateBuilder.ownParams (http://localhost:1337/assets/bower_components/ionic/js/ionic.bundle.js:39862:7)
    at registerState (http://localhost:1337/assets/bower_components/ionic/js/ionic.bundle.js:39981:72)
    at $StateProvider.state (http://localhost:1337/assets/bower_components/ionic/js/ionic.bundle.js:40466:5)
    at $StateProvider.IonicModule.factory.config.$stateProvider.state (http://localhost:1337/assets/bower_components/ionic/js/ionic.bundle.js:46208:31)
    at http://localhost:1337/app/app.module.js:159:6
    at Object.invoke (http://localhost:1337/assets/bower_components/ionic/js/ionic.bundle.js:12884:17)
http://errors.angularjs.org/1.3.13/$injector/modulerr?p0=westBay&p1=TypeErr…37%2Fassets%2Fbower_components%2Fionic%2Fjs%2Fionic.bundle.js%3A12884%3A17)

#15

Are you passing in an array as the parameter? I believe it must be a dictionary / js object … You could just do {‘something’: null’} and that should work.


#16

Yes, generally you’ll want to pass in an object where the params match your routing rules.


#17

yes, this what worked for me

controller: ...
params: { 'context': null },

as soon i pass a list, i also get that error.


#18

This feature was added recently: Its called dynamic params - one need to pass { dynamic: true } for making the param take value which is sent as part of

 $state.go(state,{paramName:"xyz"})

params: { paramName: { dynamic: true } }

#19

that message comes from versions of ui-router 0.2.10 and earlier and those versions don’t support passing objects as parameters.


#20

Hello, I’d faced a similar problem. I ended up with a working solution after a lot of googling and trial and test. Here is my solution which would work for you.

I have two controllers - searchBoxController and stateResultController and a parameter named searchQuery to be passed from a view having a search box to a view showing the results fetched from a remote server. This is how you do it:

Below is the controller from which you call the next view using $state.go()

 .controller('searchBoxController', function ($scope, $state) {
		$scope.doSearch = function(){
			var searchInputRaw = $scope.searchQueryInput;
			$state.go('app.searchResults', { searchQuery: searchInput });
		}
	})

Below is the state that would be called when the $state.go() gets executed:

.state('app.searchResults', 
			{
				url: '/searchResults',
				views:
				{
					'menuContent': { templateUrl: 'templates/searchResult.html', controller: 'stateResultController' }
				},
  				params: 
				{
					'searchQuery': ''
  				}
			})

And finally, the controller associated with the app.searchResults state:

.controller('stateResultController', function ($scope, $state, $stateParams, $http) {
		$scope.searchQueryInput = $stateParams.searchQuery;
	});