Reputation: 9389
Right now I have a simple angular set up that has a login state and a cloud state. I want to make it so the cloud state can only be run if a user is authenticated. And if not, it will direct them to the login state.
So far I believe I have the "resolve" setup and I have the .run()
function set up to redirect to the login state if there the resolve fails.
I am just having trouble figuring out how I can make authenticated: authenticated
get what I need. I know I have to make an authenticated
function somewhere, I just don't know the correct way at going about it.
I'm new to angular, so If anyone has any suggestions, I'd gladly appreciate them.
var routerApp = angular.module('app', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/cloud');
$stateProvider
.state('login', {
url: '/login',
templateUrl: "pages/templates/login.html"
})
.state('cloud', {
url: '/cloud',
templateUrl: "pages/templates/account.html",
resolve: { authenticated: authenticated }
})
})
.run(function ($rootScope, $state, $log) {
$rootScope.$on('$stateChangeError', function () {
$state.go('login');
});
});
Upvotes: 3
Views: 9733
Reputation: 123861
There is nothing so complicated about resolve, check the documentation:
You can use resolve to provide your controller with content or data that is custom to the state. resolve is an optional map of dependencies which should be injected into the controller.
If any of these dependencies are promises, they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.
...
Examples:
Each of the objects in resolve below must be resolved (via deferred.resolve() if they are a promise) before the controller is instantiated. Notice how each resolve object is injected as a parameter into the controller.
$stateProvider.state('myState', {
resolve:{
// Example using function with simple return value.
// Since it's not a promise, it resolves immediately.
simpleObj: function(){
return {value: 'simple!'};
},
...
In case you want some working plunker, there is similar Q & A:
If we would like to get DRY into play, we should start to think about state hierarchy (parent / child / ...). As discussed here:
We can introduce some super 'root'
state for some general purpose:
$stateProvider
.state('root', {
abstract : true,
// see controller def below
controller : 'RootCtrl',
// this is template, discussed below - very important
template: '<div ui-view></div>',
// resolve used only once, but for available for all child states
resolve: {
user: function (authService) {
return authService.getUserDetails();
}
}
})
That would mean, that each child state, will be provided with resolve (already being resolved) for grand-parent ('root').
In case, we want to distinguish parent and child resolves we can do that, with default resolve names... Check the details here:
In case we would like also to solve deny, we can just ask for $state
provider and redirect. The best place would be some kind of change state listener. There is a detailed description how to use $rootScope.$on('$stateChangeStart',
for authentication purposes
Confusing $locationChangeSuccess and $stateChangeStart
Upvotes: 8