So I am having trouble with stateParams - I have done this before and have never had an issue but I can't seem to pass anything to the state when I call go.
If you look at the demographics section you can see that I am returning a function for the template URL and it works just fine when I hard code the GUID however my personId variable is always undefined. I am trying to figure out what I have done to cause this however I can't for the life of me.
memberApp.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider.state('quickScreen', {
url: "#/Components/QuickScreen",
templateUrl: "/Components/QuickScreen/index.html",
controller: "quickScreenController",
});
$stateProvider.state('quickScreen.detail', {
url: '#/quickScreen/:step',
templateUrl: function ($stateParams) {
console.log($stateParams.step);
return "/Components/QuickScreen/" + $stateParams.step + "/" + $stateParams.step + ".html";
}
});
$stateProvider.state('demographics', {
views: {
"memberDemographics": {
templateUrl: function ($stateParams) {
console.log("PersonId: " + $stateParams.personId);
//return '/Demographics/Index/' + $stateParams.personId;
return '/Demographics/Index/' + 'f75fb494-xxxx-xxxx-xxxx-a17b01336ca5';
},
controller: 'demographicsSearchController'
}
},
});
});
memberApp.controller('memberAppController', function ($scope, $state, $stateParams) {
console.log("About to load to demographics");
$state.go('demographics', { personId: 'f75fb494-fe7a-4564-be93-a17b01336ca5' });
});
You can try with this ,We can take Particular Id from stateParams and assign to some variable you can use that variable or u can user direactly
( $state.go('demographics', { personId: $stateParams.personId });).
memberApp.controller('memberAppController','$stateParams','$scope','$scope',
function ($scope,$state, $stateParams)
{
console.log("About to load to demographics");
var Id = $stateParams.personId;
$state.go('demographics', { personId: Id });
});
Related
I am using a $stateprovider as follows from angular-ui-router in my angular application:
.state('order', {
url: "/order/:id",
templateUrl: "/myapp/order"
})
In the above scenario, we are passing an id to the controller and we can call it as ui-sref="order({id: 1234})".
But now i want to make a direct call to the backend by not using a controller and pass the above as follows:
.state('order', {
url: "/order",
templateUrl: "/myapp/order/:id"
})
But obviously my syntax is wrong here.
How do i achieve this scenario?
I created working example. It is adjsuting thiw Q & A:
Trying to Dynamically set a templateUrl in controller based on constant
Let's have templates template-A.html and template-B.html in our example.
The state def with templateProvider would look like this
$stateProvider
.state('order', {
url: '/order/:id',
templateProvider: function($http, $templateCache, $stateParams) {
var id = $stateParams.id || 'A';
var templateName = 'template-' + id + '.html';
var tpl = $templateCache.get(templateName);
if (tpl) {
return tpl;
}
return $http
.get(templateName)
.then(function(response) {
tpl = response.data
$templateCache.put(templateName, tpl);
return tpl;
});
},
controller: function($state) {}
});
And now we can call it like this
<a href="#/order/A">
<a href="#/order/B">
Check it here
And what's more, with latest version of angularjs we can even make it super simple:
$templateRequest
Updated plunker
.state('order', {
url: '/order/:id',
templateProvider: function($templateRequest, $stateParams) {
var id = $stateParams.id || 'A';
var templateName = 'template-' + id + '.html';
return $templateRequest(templateName);
},
controller: function($state) {}
});
I am confused. For a long time now I have been using stateParams as a means of find out the stateParams inside a templateUrl.
Now I tried to do the same in a resolve and it does not work. In fact nothing happens when I use stateParams.
However by chance I found that I can use $stateParams in the resolve and it works.
Can someone tell me what is the difference and why do I need to use stateParams in the templateUrl and $stateParams in the resolve?
var auth = {
name: 'auth',
url: '/Auth/:content',
templateUrl: function (stateParams) {
var page = 'app/auth/partials/' + stateParams.content + '.html';
return page;
},
controller: function ($scope, authService) {
$scope.aus = authService;
},
resolve:
{
init: function ($stateParams) {
var x = 99;
return true;
}
}
};
I've created working example here, showing that $statePrams are accessible in the resolve
// States
$stateProvider
.state('auth', {
url: "/auth/:content",
templateUrl: 'tpl.html',
controller: 'AuthCtrl',
resolve : {
init : ['$stateParams' , function($stateParams){
return { resolved: true, content: $stateParams.content };
}]
}
})
Controller
.controller('AuthCtrl', ['$scope', 'init', function ($scope, init) {
$scope.init = init;
}])
and this could be the calls
auth/8
auth/xyz
Check it here
I think this is just basically a question of syntax, but I have this routing set up:
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('addAlbum', {
url: "/albums/create/:artistId",
templateUrl: "public/albums/views/album.tpl.html",
controller: "createAlbumController",
data: {
pageTitle: 'Create Album'
},
resolve: {
albums: function (publicArtistServices) {
return publicArtistServices.getAlbums(1);
}
}
});
}]);
And I need that getAlbums() method to use the artistId passed in on the URL:
return publicArtistServices.getAlbums({need artistId from URL here});
I tried guessing at it by using return publicArtistServices.getAlbums($state.params[0]); but that just threw a "$state is not defined" error.
What's the right syntax here?
$stateParams is what you want to use for this.
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('addAlbum', {
url: "/albums/create/:artistId",
templateUrl: "public/albums/views/album.tpl.html",
controller: "createAlbumController",
data: {
pageTitle: 'Create Album'
},
resolve: {
albums: function ($stateParams, publicArtistServices) {
return publicArtistServices.getAlbums($stateParams.artistId);
}
}
});
}]);
You need to include the $state parameter (to "inject" it into your function):
albums: function ($state, publicArtistServices) {
return publicArtistServices.getAlbums($state.params[0]);
}
If that doesn't work, use $route.current.params.artistId as shown here:
https://stackoverflow.com/a/13433335/584846
Besides ui-router, I am using ui-bootstrap's $modal service.
I use resolves (actually passed inside a modal) on the onEnter property of the state (with url parameters) to activate modals (as mentioned in the docs|FAQ of ui-router).
I tried to access the $stateParams, however it seems to be an empty object when the resolves fire.
function onEnter($modal, $state) {
// simple handler
function transitionToOverlay() {
return $state.transitionTo('parent');
}
// actual modal service
$modal
.open({
size: 'sm',
resolve: { getY: getY },
controller: 'ChildCtrl as child',
template: template
})
.result
.then(transitionToOverlay)
.catch(transitionToOverlay);
}
// resolve
function getY($state, $stateParams) {
console.log('State resolve getY...');
console.log($stateParams); // returns {} empty object
return 'y'; // just a dummy resolve
}
Here's a plnkr for demonstration purposes.
UI-Router doesn't have any control over your $modal call. Resolves should go on state definitions if you would like UI-Router to inject them.
var state = {
url: '{id}',
name: 'parent.child',
resolve: { getY: getYfn }, // moved from $modal call
onEnter: function(getY) { // injected into onEnter
$modal.open({
resolve: { getY: function () { return getY; } }, // passed through to $modal.open
controller: 'ChildCtrl as child', // ChildCtrl injects getY
});
}
}
Just posting this in case someone has the same problem...
I had the same problem as in the original question but the selected answer didn't help me too much since I couldn't get to access the resolve defined directly in the state inside my modal controller.
However, I noticed $stateParams is still accessible in the onEnter function so it is possible to create a variable here and then use this variable inside the $modal.open() function.
.state('parent.child', {
url: 'edit/:id',
// If defining the resolve directly in the state
/*resolve: { // Here $stateParams.id is defined but I can't access it in the modal controller
user: function($stateParams) {
console.log('In state(): ' + $stateParams.id);
return 'user ' + $stateParams.id;
}
},*/
onEnter: function($modal, $stateParams, $state) {
var id = $stateParams.id; // Here $stateParams.id is defined so we can create a variable
$modal.open({
templateUrl: 'modal.html',
// Defining the resolve in the $modal.open()
resolve: {
user: function($stateParams) {
console.log('In $modal.open(): ' + $stateParams.id); // Here $stateParams.id is undefined
console.log(id); // But id is now defined
return 'user ' + id;
}
},
controller: ChildCtrl,
controllerAs: 'ctrl'
})
.result
.then(function(result) {
return $state.go('^');
}, function(reason) {
return $state.go('^');
});
}
})
Here is an example plnkr : http://plnkr.co/edit/wMMXDSsXLABFr0P5q2On
Also, if needing to define the resolve function outside the configuration object, we can do it like this:
var id = $stateParams.id;
$modal.open({
resolve: {
user: myResolveFunction(id)
},
...
});
And:
function myResolveFunction(id) {
return ['MyService', function(MyService) {
console.log('id: ' + id);
return MyService.get({userId: id});
}];
}
I have the following states set up:
var questions = {
name: 'questions',
url: '/questions',
views: {
'menu': {
templateUrl: function (stateParams) {
return '/Content/app/questions/partials/menu.html'
},
controller: 'QuestionsMenuController'
},
}
}
var questionsContent = {
name: 'questions.content',
parent: 'questions',
url: '/:content',
views: {
'content#': {
templateUrl: function (stateParams) {
var isNumber = !isNaN(parseFloat(stateParams.content));
return isNumber ? '/Content/app/questions/partials/detail.html' :
'/Content/app/questions/partials/content.html'
},
controller: 'QuestionsContentController'
},
}
}
and:
$stateProvider
.state(questions)
.state(questionsContent);
When I go my menu with /questions then the controller gets a list of questions and populates the $scope.questionHeaders object.
var url = '/api/Question/GetQuestionHeaders?id=0';
$http.get(url)
.success(function (data, status, headers, config) {
$scope.questionHeaders = data;
$scope.currentQuestion = $scope.questionHeaders[0].questionId;
$state.transitionTo('questions.content', { content: $scope.currentQuestion })
})
.error(function (data, status, headers, config) {
alert("Error: No data returned from " + url);
});
Following this I want to transition to the first in the list so I coded:
$state.transitionTo('questions.content', { content: $scope.currentQuestion })
However when I trace this it just stays in an infinte loop and it does not go to the new /questions/5 (when 5 is the questionHeaders[0].questionId).
Can someone give me some advice as to how I can make it transition to /questions/5 ? I am happy if it goes to the new browser href but do I need to code that directly (how) or can ui-router do this for me?
You can inject the $state service, and call it's transitionTo (go) method.
.controller('SomeController', ['$state', function($state){
$state.transitionTo('my.state', {arg:'arg'});
}]);
#Cody's question:
You can also inject the $stateParams into your controller and go to a state with args:
.controller('SomeController', ['$state', '$stateParams', function($state, $stateParams){
$state.go('my.state', {listId: $stateParams.listId, itemId: $stateParams.itemId});
}]);