I am using AngularJS v1.2.0-rc.2 with ui-router v0.2.0. I want to pass the referrer state to another state so I use the toParams of $state.go like so:
$state.go('toState', {referer: $state.current.name});
According to the docs, this should populate the $stateParams on the toState controller, but it is undefined. What am I missing?
I've created a plunk to demonstrate:
http://plnkr.co/edit/ywEcG1
If you want to pass non-URL state, then you must not use url when setting up your state. I found the answer on a PR and did some monkeying around to better understand.
$stateProvider.state('toState', {
templateUrl:'wokka.html',
controller:'stateController',
params: {
'referer': 'some default',
'param2': 'some default',
'etc': 'some default'
}
});
Then you can navigate to it like so:
$state.go('toState', { 'referer':'jimbob', 'param2':37, 'etc':'bluebell' });
Or:
var result = { referer:'jimbob', param2:37, etc:'bluebell' };
$state.go('toState', result);
And in HTML thusly:
<a ui-sref="toState(thingy)" class="list-group-item" ng-repeat="thingy in thingies">{{ thingy.referer }}</a>
This use case is completely uncovered in the documentation, but I think it's a powerful means on transitioning state without using URLs.
The Nathan Matthews's solution did not work for me but it is totally correct but there is little point to reaching a workaround:
The key point is: Type of defined parameters and toParamas of $state.go should be same array or object on both sides of state transition.
For example when you define a params in a state as follows you means params is array because of using "[]":
$stateProvider
.state('home', {
templateUrl: 'home',
controller: 'homeController'
})
.state('view', {
templateUrl: 'overview',
params: ['index', 'anotherKey'],
controller: 'overviewController'
})
So also you should pass toParams as array like this:
params = { 'index': 123, 'anotherKey': 'This is a test' }
paramsArr = (val for key, val of params)
$state.go('view', paramsArr)
And you can access them via $stateParams as array like this:
app.controller('overviewController', function($scope, $stateParams) {
var index = $stateParams[0];
var anotherKey = $stateParams[1];
});
Better solution is using object instead of array in both sides:
$stateProvider
.state('home', {
templateUrl: 'home',
controller: 'homeController'
})
.state('view', {
templateUrl: 'overview',
params: {'index': null, 'anotherKey': null},
controller: 'overviewController'
})
I replaced [] with {} in params definition. For passing toParams to $state.go also you should using object instead of array:
$state.go('view', { 'index': 123, 'anotherKey': 'This is a test' })
then you can access them via $stateParams easily:
app.controller('overviewController', function($scope, $stateParams) {
var index = $stateParams.index;
var anotherKey = $stateParams.anotherKey;
});
All I had to do was add a parameter to the url state definition like so
url: '/toState?referer'
Doh!
Not sure if it will work with AngularJS v1.2.0-rc.2 with ui-router v0.2.0.
I have tested this solution on AngularJS v1.3.14 with ui-router v0.2.13.
I just realize that is not necessary to pass the parameter in the URL as gwhn recommends.
Just add your parameters with a default value on your state definition.
Your state can still have an Url value.
$stateProvider.state('state1', {
url : '/url',
templateUrl : "new.html",
controller : 'TestController',
params: {new_param: null}
});
and add the param to $state.go()
$state.go('state1',{new_param: "Going places!"});
None of these examples on this page worked for me. This is what I used and it worked well. Some solutions said you cannot combine url with $state.go() but this is not true. The awkward thing is you must define the params for the url and also list the params. Both must be present. Tested on Angular 1.4.8 and UI Router 0.2.15.
In the state add your params to end of state and define the params:
url: 'view?index&anotherKey',
params: {'index': null, 'anotherKey': null}
In your controller your go statement will look like this:
$state.go('view', { 'index': 123, 'anotherKey': 'This is a test' });
Then to pull the params out and use them in your new state's controller (don't forget to pass in $stateParams to your controller function):
var index = $stateParams.index;
var anotherKey = $stateParams.anotherKey;
console.log(anotherKey); //it works!
In my case I tried with all the options given here, but no one was working properly (angular 1.3.13, ionic 1.0.0, angular-ui-router 0.2.13). The solution was:
.state('tab.friends', {
url: '/friends/:param1/:param2',
views: {
'tab-friends': {
templateUrl: 'templates/tab-friends.html',
controller: 'FriendsCtrl'
}
}
})
and in the state.go:
$state.go('tab.friends', {param1 : val1, param2 : val2});
Cheers
I've spent a good deal of time fighting with Ionic / Angular's $state & $stateParams;
To utilize $state.go() and $stateParams you must have certain things setup and other parameters must not be present.
In my app.config() I've included $stateProvider and defined within it several states:
$stateProvider
.state('home', {
templateUrl: 'home',
controller: 'homeController'
})
.state('view', {
templateUrl: 'overview',
params: ['index', 'anotherKey'],
controller: 'overviewController'
})
The params key is especially important. As well, notice there are NO url keys present... utilizing stateParams and URLs do NOT mix. They are mutually exclusive to each other.
In the $state.go() call, define it as such:
$state.go('view', { 'index': 123, 'anotherKey': 'This is a test' })
The index and anotherKey $stateParams variables will ONLY be populated if they are first listed in the $stateController params defining key.
Within the controller, include $stateParams as illustrated:
app.controller('overviewController', function($scope, $stateParams) {
var index = $stateParams.index;
var anotherKey = $stateParams.anotherKey;
});
The passed variables should be available!
Try With reload: true?
Couldn't figure out what was going on for the longest time -- turns out I was fooling myself. If you're certain that things are written correctly and you will to use the same state, try reload: true:
.state('status.item', {
url: '/:id',
views: {...}
}
$state.go('status.item', { id: $scope.id }, { reload: true });
Hope this saves you time!
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;
});
And in my case of a parent/child state. all the parameters declared in child state has to be known by the parent state
.state('full', {
url: '/full',
templateUrl: 'js/content/templates/FullReadView.html',
params: { opmlFeed:null, source:null },
controller: 'FullReadCtrl'
})
.state('full.readFeed', {
url: '/readFeed',
views: {
'full': {
templateUrl: 'js/content/templates/ReadFeedView.html',
params: { opmlFeed:null, source:null },
controller: 'ReadFeedCtrl'
}
}
})
The solution we came to having a state that took 2 parameters was changing:
.state('somestate', {
url: '/somestate',
views: {...}
}
to
.state('somestate', {
url: '/somestate?id=:&sub=:',
views: {...}
}
Your define following in router.js
$stateProvider.state('users', {
url: '/users',
controller: 'UsersCtrl',
params: {
obj: null
}
})
Your controller need add $stateParams.
function UserCtrl($stateParams) {
console.log($stateParams);
}
You can send an object by parameter as follows.
$state.go('users', {obj:yourObj});
I was trying to Navigate from Page 1 to 2, and I had to pass some data as well.
In my router.js, I added params name and age :
.state('page2', {
url: '/vehicle/:source',
params: {name: null, age: null},
.................
In Page1, onClick of next button :
$state.go("page2", {name: 'Ron', age: '20'});
In Page2, I could access those params :
$stateParams.name
$stateParams.age
If this is a query parameter that you want to pass like this:
/toState?referer=current_user
then you need to describe your state like this:
$stateProvider.state('toState', {
url:'toState?referer',
views:{'...'}
});
source: https://github.com/angular-ui/ui-router/wiki/URL-Routing#query-parameters
Related
I am trying to add a parameter to my angular application. actually my app will dynamically called as :
"https://abc.ss.com/xx/sn=1234568505
to handle this state - in my $stateProvider - I am trying like this:
.state('serialCreateCase', {
url: '/sn=*', //but not working
templateUrl:'abxy.html',
controller: 'controllersss as ctrl',
}
})
But my URL is not capturing redirecting to default page. how to add the = parameter?
Try this:
.state('serialCreateCase', {
url: '^/sn={id}',
params: {
id: {}
},
templateUrl:'abxy.html',
controller: 'controllersss as ctrl',
}
That should match the url you're expecting.
Edit: answer has been updated to change it to required parameters.
Did you try this: http://benfoster.io/blog/ui-router-optional-parameters
Query Parameters
So that query parameters are mapped to UI Router's $stateParams object, you need to declare them in your state configuration's URL template:
state('new-qs', {
url: '/new?portfolioId',
templateUrl: 'new.html',
controller: function($scope, $stateParams) {
$scope.portfolioId = $stateParams.portfolioId;
}
})
You can then create a link to this state using the ui-sref attribute:
<a ui-sref="new-qs({ portfolioId: 1 })">New (query string)</a>
This will navigate to /new?portfolioId=1.
If you have multiple optional parameters, separate them with an &:
state('new-qs', {
url: '/new?portfolioId¶m1¶m2',
templateUrl: 'new.html',
controller: function($scope, $stateParams) {
$scope.portfolioId = $stateParams.portfolioId;
$scope.param1 = $stateParams.param1;
$scope.param2 = $stateParams.param2;
}
})
You could add params like this
state('serialCreateCase', {
url: '/xx?sn',
templateUrl: 'abxy.html',
controller: 'controllersss as ctrl',
}
})
The state ref will be
<a ui-sref="serialCreateCase({ sn: 1234568505 })">URL</a>
I have a route:
.state('list', {
url:'/list?query',
templateUrl: '/views/list.html',
controller: 'ListCtrl as vm'
})
Is there a way to ensure a default value for the query?
I don't want to do it in the controller, as I use the same controller for other routes, and the controller has certain behaviour if the query is undefined.
What I want is this particular route to default that query.
In the old angular route I have done this sort of thing...
.when('/list',
templateUrl: '/views/list.html',
controller: 'ListCtrl'
controllerAs:true,
redirectTo:function(routeParams, path, search) {
if(!search.query) {
return "list?query=defaultSearch";
}
}
})
You could use the onEnter method to execute logic before your controller loads.
From the ui-router wiki https://github.com/angular-ui/ui-router/wiki:
$stateProvider.state("contacts", {
template: '<h1>{{title}}</h1>',
resolve: { title: 'My Contacts' },
controller: function($scope, title){
$scope.title = title;
},
onEnter: function($location){
if($location){ ... do something ... }
}
})
We can use a setting called params. There is a working plunker
.state('list', {
url:'/list?query',
templateUrl: 'views/list.html',
controller: 'ListCtrl as vm',
params: { query: 'DEFAULT VALUE' }, // here the default
})
and these links will work as expected
<a href="#/list?"> - with default 'query' value
<a href="#/list?query=someParam">
<a ui-sref="list({query:'theParam'})">
Check it in action here
The details are discussed here:
Angular ui router passing data between states without URL
If I am getting you right, you need to go to a state if the user requested state does not match any of the states defined.
If this is the requirement, then try using "otherwise" method of $urlRouterProvider
like,
$urlRouterProvider.otherwise("/default-state");
Can someone explain how to use parameters sent with $state.go? In CreatePollController I create a poll which I send to the state add_data_poll (AddDataPollController), but I really don't know how to access this parameter to display it in the view or use it in the controller (I tried to see the response with console.log($scope.response), but it doesn't work), can anyone explain me?
angular.module('estudios')
.controller('CreatePollController', ['$scope', 'Restangular', '$state',
function($scope, Restangular, $state) {
$scope.addPoll = function() {
if ($scope.allow_anonymous_answer == null)
$scope.allow_anonymous_answer = false
var poll = {title: $scope.title, description: $scope.description, allow_anonymous_answer: $scope.allow_anonymous_answer, initial_message: $scope.initial_message, final_message: $scope.final_message};
Restangular.all('polls').post(poll).then(function(response) {
$state.go('add_data_poll', response);
});
};
}])
.controller('AddDataPollController', ['$scope', 'Restangular',
function($scope, Restangular) {
}]);
And these are the corresponding states.
.state('create_poll', {
url: '/create_poll',
parent: 'home',
templateUrl: 'poll/create_poll.html',
controller: 'CreatePollController'
})
.state('add_data_poll', {
url: '/create_poll/add_data_poll',
parent: 'home',
templateUrl: 'poll/add_data_poll.html',
controller: 'AddDataPollController'
You need to have either params defined in your state or query params defined in your state url.
Example for state params:
.state('add_data_poll', {
url: '/create_poll/add_data_poll',
params: {
// define object with parameters that you want to pass
// Example:
id: 1 // 1 is the default parameter if no id is passed
}
parent: 'home',
templateUrl: 'poll/add_data_poll.html',
controller: 'AddDataPollController'
This way you can send parameters but they won't be available in the query string and upon refresh they will be lost.
Example for defining query parameters:
.state('add_data_poll', {
url: '/create_poll/add_data_poll?someParameter&anotherOne',
parent: 'home',
templateUrl: 'poll/add_data_poll.html',
controller: 'AddDataPollController'
someParameter and anotherOne will be available if you pass them from the incoming state.
When passing parameters you should define what parameters you are passing.
$state.go('some.route', {id: 2, someParam: 'coolParam');
And then you can access them with $stateParams in the controller. But first you need to inject it.
myApp.controller('myCtrl', function($stateParams) {
console.log($stateParams);
});
It is not good idea to pass the whole response from an API. Better will be if you choose just the stuff you need from the response and build your state around them.
Read more about ui-router state params HERE
I can't retrieve parameters passed from ui-router in Ionic.
Parameters passed into the Controller are undefined
This is my state code:
.state('app.dayliston', {
cache: false,
url: '/myurl',
views: {
'mainContent': {
templateUrl: 'calendar/daylist.html',
controller: 'MyCtrl',
params : { 'mode':'online'}
}
}
})
and here is My Controller code:
.controller('MyCtrl', function($scope,$state, $stateParams,CalendarFactory,FBFactory, $ionicHistory,$ionicScrollDelegate,$ionicModal,$ionicPopup, $timeout) {
console.log('MyCtrl')
console.log('mode'+$stateParams.mode) // mode is undefined
....
})
I'm using 1.6.1. Is there anything wrong with my code?
As I can see in your code, you dont need to use $stateParams because you don't get the "mode" parameter from the URL.
I think attached data in state will be a better choice (Docs):
.state('app.dayliston', {
cache: false,
url: '/myurl',
data:{
mode: 'online'
},
views: {
'mainContent': {
templateUrl: 'calendar/daylist.html',
controller: 'MyCtrl'
}
}
})
Then you can get the data stored in state like this:
.controller('MyCtrl', function($scope, $state, $stateParams, CalendarFactory, FBFactory, $ionicHistory, $ionicScrollDelegate, $ionicModal, $ionicPopup, $timeout) {
console.log('MyCtrl')
console.log('mode'+$state.current.data.mode) // "online"
})
MyCtrl is the actual name of your controller. It's not a parameter that's passed to the controller per se.
Route:
.state('app.dayliston', {
cache: false,
url: '/myurl/:mode',
views: {
'mainContent': {
templateUrl: 'calendar/daylist.html',
controller: 'MyCtrl'
}
}
})
Check URL Routing Query Parameters doc
Link from view:
<a ui-sref="app.dayliston({mode: 'online'});">Go to dayliston</a>
Go to state/route from controller:
$state.go('app.dayliston', {mode: 'online'});
you are passing the $stateParams incorrectly
https://github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service
The should be on the url or you can pass data in using the resolve map on the state.
https://github.com/angular-ui/ui-router/wiki#resolve
also passing in custom data might be a better approach? Hard to tell from the code sample you provided
Trying to pass on a parameter to my ui router:
$state.go('orderDetail', {myParam: {accountID: $scope.selectedAccount}})
In my stateprovider the orderDetail state looks like this:
.state('orderDetail', {
templateUrl: 'modules/common/orders/partials/detail.html?referrer',
controller: 'OrderDetailCtrl',
url: '/detail/:myParam',
resolve: {
orderDetails: function (myservice, configService, $stateParams) {
console.log('resolve');
var referrer = $stateParams.myParam;
debugger;
console.log('stateParm', referrer.accountID);
console.log('order detail resolving');
//todo remove hardcoded
return myservice.getDetail(configService.config('mock_order_detail').url + '?accountId=2233');
}
}
});
However console.log('stateParm', referrer.accountID); shows up as undefined. How can I pass in the accountID param?
To recognize the state that myParam is object, you need to define its default value inside your state params option, by assigning null or any default value you want for it.
Code
.state('orderDetail', {
templateUrl: 'modules/common/orders/partials/detail.html?referrer',
controller: 'OrderDetailCtrl',
url: '/detail/:myParam',
resolve: {
//resolve code here
}
params: {
'myParam': null
}
}
To make above changes effective you Should update ui-router version to 0.2.13
Github Issue Link
$stateParams accepts only string, however you could stringify your object as pass it as myParam
$state.go('orderDetail', {myParam: angular.fromJson({accountID: $scope.selectedAccount})})
and then
.state('orderDetail', {
templateUrl: 'modules/common/orders/partials/detail.html?referrer',
controller: 'OrderDetailCtrl',
url: '/detail/:myParam',
resolve: {
orderDetails: function (myservice, configService, $stateParams) {
var referrer = angular.toJson($stateParams.myParam);
return myservice.getDetail(configService.config('mock_order_detail').url + '?accountId=2233');
}
}
});
But i don't recommend using stringified objects, better use a service as bridge for states, just because makes ugly URL and not secure, internal state must be hidden from user i belive