I am new to AngularJS, and I am a little confused of how I can use angular-\"ui-router\" in the following scenario:
I am building a web application which consists of
The solutions posted so far are needlessly complicated, in my opinion. There's a simpler way. The documentation of ui-router says listen to $locationChangeSuccess and use $urlRouter.sync() to check a state transition, halt it, or resume it. But even that actually doesn't work.
However, here are two simple alternatives. Pick one:
$locationChangeSuccessYou can listen to $locationChangeSuccess and you can perform some logic, even asynchronous logic there. Based on that logic, you can let the function return undefined, which will cause the state transition to continue as normal, or you can do $state.go('logInPage'), if the user needs to be authenticated. Here's an example:
angular.module('App', ['ui.router'])
// In the run phase of your Angular application
.run(function($rootScope, user, $state) {
// Listen to '$locationChangeSuccess', not '$stateChangeStart'
$rootScope.$on('$locationChangeSuccess', function() {
user
.logIn()
.catch(function() {
// log-in promise failed. Redirect to log-in page.
$state.go('logInPage')
})
})
})
Keep in mind that this doesn't actually prevent the target state from loading, but it does redirect to the log-in page if the user is unauthorized. That's okay since real protection is on the server, anyway.
resolveIn this solution, you use ui-router resolve feature.
You basically reject the promise in resolve if the user is not authenticated and then redirect them to the log-in page.
Here's how it goes:
angular.module('App', ['ui.router'])
.config(
function($stateProvider) {
$stateProvider
.state('logInPage', {
url: '/logInPage',
templateUrl: 'sections/logInPage.html',
controller: 'logInPageCtrl',
})
.state('myProtectedContent', {
url: '/myProtectedContent',
templateUrl: 'sections/myProtectedContent.html',
controller: 'myProtectedContentCtrl',
resolve: { authenticate: authenticate }
})
.state('alsoProtectedContent', {
url: '/alsoProtectedContent',
templateUrl: 'sections/alsoProtectedContent.html',
controller: 'alsoProtectedContentCtrl',
resolve: { authenticate: authenticate }
})
function authenticate($q, user, $state, $timeout) {
if (user.isAuthenticated()) {
// Resolve the promise successfully
return $q.when()
} else {
// The next bit of code is asynchronously tricky.
$timeout(function() {
// This code runs after the authentication promise has been rejected.
// Go to the log-in page
$state.go('logInPage')
})
// Reject the authentication promise to prevent the state from loading
return $q.reject()
}
}
}
)
Unlike the first solution, this solution actually prevents the target state from loading.