Using ui-router and attempting to pass URL query parameters to the controller in the .config
of the module, using a .service
that has been injected into the resolve
argument of the .state
definition.
Preferred Method - (not working reliably)
.state('list', {
url: '/list?country&state&city',
templateUrl: "list.html",
controller : 'myController',
resolve: {
currentUrlTypeParam : ['myServices', function(myServices){ // object variable that can be injected into specified controller
return myServices.getUrlTypeParams();
}]
}
})
While the documentation says that only Constant and Provider recipes can be injected into the .config
function of a module, I'm following this method of injecting a .service
into the resolve
argument of the .state
definition.
The reason I'm using a service is that I have a number of states with the same URL query parameters - so it makes sense to write the function once as a service provider rather than repeating it.
I'm using resolve
rather than just injecting $stateParams
directly into the controller so that I can complete server calls during config.
Here's a plunker of this (showing 3 possible states with the same URL parameters) - however it doesn't work reliably - the correct URL params seem to arrive on a 2nd click to a different URL in the same state.
Even more frustrating is that while the $stateParams
seems to arrive correctly (on 1st click) in the .service
function - but the values come up as undefined
when trying to access them - check out the plunker console.log
to see this strange phenomena !
eg
console.log
will output $stateParams
in the .service
function as:
{country: "US", state: undefined, city: undefined}
however when I call $stateParams.country
within the function i get undefined
??
Alternative Messier Method - (working fine)
The alternative is repeating the same large .service
code within the resolve
argument of every state definition - which works reliably, but bloats the code (...and this is a simplified example of the states / params I am dealing with).
.state('list', {
url: '/list?country&state&city',
templateUrl: "list.html",
controller : 'myController',
resolve: {
currentUrlTypeParam : ['$stateParams', function($stateParams){
var urlTypeParameter = {} // define an object that we'll return as the value for $scope.loadMethodParameters
if($stateParams.country && typeof $stateParams.country !== undefined){
urlTypeParameter.type = 'country';
urlTypeParameter.parameter = $stateParams.country;
} else if($stateParams.state && typeof $stateParams.state !== undefined){
urlTypeParameter.type = 'state';
urlTypeParameter.parameter = $stateParams.state;
} else if($stateParams.city && typeof $stateParams.city !== undefined){
urlTypeParameter.type = 'city';
urlTypeParameter.parameter = $stateParams.city;
} else {
urlTypeParameter.type = 'default';
}
return urlTypeParameter;
}]
}
})
See this plunker for a rather ...inelegant way of achieving the same thing.