I am currently working on implementing authentication in my Angular application and I want to redirect to an external URL when a user is not logged in (based on a $http.get request).
However, I seem to be stuck in an infinite loop when using event.preventDefault() as the first line in the $stateChangeStart function.
I have come across various solutions on Stack Overflow suggesting to place event.preventDefault() just before the state.go in the else statement. But this results in the controllers being triggered and the page being displayed before the promise is returned.
Even when I move the event.preventDefault() to the else block, something strange happens:
When navigating to the root URL, it automatically adds /#/ after the URL and triggers $stateChangeStart multiple times.
This is how the run part of app.js looks like:
.run(['$rootScope', '$window', '$state', 'authentication', function ($rootScope, $window, $state, authentication) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
event.preventDefault();
authentication.identity()
.then(function (identity) {
if (!authentication.isAuthenticated()) {
$window.location.href = 'external URL';
return;
} else {
$state.go(toState, toParams);
}
});
});
}]);
The identity() function in authentication.factory.js:
function getIdentity() {
if (_identity) {
_authenticated = true;
deferred.resolve(_identity);
return deferred.promise;
}
return $http.get('URL')
.then(function (identity) {
_authenticated = true;
_identity = identity;
return _identity;
}, function () {
_authenticated = false;
});
}
EDIT: Here are the states defined:
$stateProvider
.state('site', {
url: '',
abstract: true,
views: {
'feeds': {
templateUrl: 'partials/feeds.html',
controller: 'userFeedsController as userFeedsCtrl'
}
},
resolve: ['$window', 'authentication', function ($window, authentication) {
authentication.identity()
.then(function (identity) {
if (!authentication.isAuthenticated()) {
$window.location.href = 'external URL';
}
})
}]
})
.state('site.start', {
url: '/',
views: {
'container@': {
templateUrl: 'partials/start.html'
}
}
})
.state('site.itemList', {
url: '/feed/{feedId}',
views: {
'container@': {
templateUrl: 'partials/item-list.html',
controller: 'itemListController as itemListCtrl'
}
}
})
.state('site.itemDetails', {
url: '/items/{itemId}',
views: {
'container@': {
templateUrl: 'partials/item-details.html',
controller: 'itemsController as itemsCtrl'
}
}
})
}])
If you require additional information or code snippets from app.js, please let me know!