I\'m making an app with dynamical states, and sometimes I need to resolve the state name from the url.
e.g.: I have /dashboard/user/12268
and I need to
The current state can be obtained from $state service. like $state.current
Check this api http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state
To get @Chris T solution to work for me I am doing this inside a Service:
app.service('Helper', ['$state', '$location',
function($state, $location){
var services = {};
services.stateIs = function(state_name){
var current_path = $location.$$path;
var state = $state.get(state_name);
if(state){
var state_regexp = state.$$state().url.regexp;
return state_regexp.test(current_path);
}else{
return false;
}
}
return services;
}
]);
So later I can inject Helper anywhere and do this:
if(Helper.stateIs('app.user')){
//yeah
}
Finally I've had to make a small modification on ui-router's $state
service to get to the solution.
It results that the states stored in the service have more information that the one given on the $state.get()
method. So I iterated over them to get a state that matches with my URL:
/**
* @ngdoc function
* @name ui.router.state.$state#fromUrl
* @methodOf ui.router.state.$state
*
* @description
* A method to resolve a state and its parameters from a given URL
*
* @returns {boolean} Returns a state that matches with the given URL, or undefined if no match
*/
$state.fromUrl = function(url) {
if(!angular.isString(url)) {
//Only valid strings allowed
return undefined;
}
var keys = objectKeys(states);
//Iterate over all states
for(var i = 0; i < keys.length; i++) {
var state = states[keys[i]];
var stateArgs = state.url.exec(url);
//If the state's URL does not match then stateArgs will be false
if(!!stateArgs) {
return {
name: state.name,
args: stateArgs
}
}
}
return undefined;
};
Regards,
Alx
https://github.com/angular-ui/ui-router/issues/1651
You can expose the internal state implementation by using the .decorator
hook on $stateProvider
. You can decorate any property of the state builder; I chose 'parent' arbitrarily.
app.config(function($stateProvider) {
$stateProvider.decorator('parent', function (internalStateObj, parentFn) {
// This fn is called by StateBuilder each time a state is registered
// The first arg is the internal state. Capture it and add an accessor to public state object.
internalStateObj.self.$$state = function() { return internalStateObj; };
// pass through to default .parent() function
return parentFn(internalStateObj);
});
});
Now you can access the internal state object using .$$state()
, e.g.
var publicState = $state.get("foo");
var privateInternalState = publicState.$$state();
Second, loop over each state in $state.get() and test them against your URL fragment.
angular.forEach($state.get(), function(state) {
var privatePortion = state.$$state();
var match = privatePortion.url.exec(url, queryParams);
if (match) console.log("Matched state: " + state.name + " and parameters: " + match);
});