Snippet:
angular
.module('mean-starter')
.run(run)
;
function run($rootScope, Auth, $state) {
function stopStateChange (message, event, redirect) {
console.log(event);
event.preventDefault();
alert(message);
if (redirect) {
$state.go(redirect);
}
}
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
if (typeof toState.authenticate === 'undefined') { // this route doesn't require permissions
return;
}
event.preventDefault(); // WORKS HERE
Auth
.getCurrentUser()
.then(function (currentUser) {
event.preventDefault(); // DOESN'T WORK HERE
var isLoggedIn = !!currentUser._id;
var isAdmin = isLoggedIn && currentUser.role === 'admin';
var isAuthorized = isLoggedIn && currentUser._id.toString() === toParams.id;
if (toState.authenticate.loggedOut && isLoggedIn) { // this route requires you to be logged out
stopStateChange("You're logged in.", event);
}
else if (!isLoggedIn) {
stopStateChange('Must be logged in to access this route.', event, 'login');
}
else if (toState.authenticate.authorized && !isAuthorized && !isAdmin) {
stopStateChange('You are not authorized to access that route.', event);
}
else if (toState.authenticate.isAdmin && !isAdmin) {
debugger;
event.preventDefault();
stopStateChange('You must be an admin to access this route.', event);
}
})
;
});
}
Upon logging in as a non-admin and visiting localhost:3000/admin
:
- An alert pops up with the message, "You must be an admin to access this route."
- I am directed to the admin page where I can see all restricted content.
Why is this happening?
When examining in the debugger, the event.preventDefault
seems to be executed. Here's the event
object displayed:
https://i.sstatic.net/oxTKO.png
The defaultPrevented
property is set to true
!
UPDATE: The behavior works outside of the .then
block but fails within it. Surprisingly, even though defined inside .then
.
UPDATE 2: It appears that the event
triggers its default action BEFORE reaching the .then
, making the .then
too late for interception.