I have states that have a requiredlogin
object set as true
, then I have Angular listen on stateChangeStart
, but things end up pretty ugly.
Here is a state that requires a login. I think this actually pretty good and simple.
.state('dashboard',
url: '/dashboard',
templateUrl: 'partials/dashboard/main.jade',
data:
requireLogin: true
)
This is where it gets ugly. I'll eventually just change this into a loginCheck()
function but I hate the logic so much; too many if
statements. Also, this barely works, so I could use the improvements.
$rootScope.$on('$stateChangeStart', (event, toState) ->
# Checks if a page or a page's parent page requires login
if _.has(toState.data, 'requireLogin')
if _.has($window.sessionStorage, 'userInfo')
# If it does check for stored user information
userInfo = JSON.parse($window.sessionStorage["userInfo"]) or null
# Check if user info has an ID property if it does try to authorize it
if _.has(userInfo, '_id')
AuthService.isAuthentic(userInfo._id).then (d) ->
if d.data == "true"
$rootScope.userInfo = userInfo
$rootScope.userAuth = true
else
$rootScope.userInfo = null
$rootScope.userAuth = false
$state.go('login')
else
event.preventDefault()
$state.go('login')
else
$window.sessionStorage["userInfo"] = null
$state.go('login')
)
-
2\$\begingroup\$ Welcome to Code Review! Could you clarify what you mean by "this barely works"? What is wrong with the code? \$\endgroup\$200_success– 200_success2014年11月11日 07:23:56 +00:00Commented Nov 11, 2014 at 7:23
-
\$\begingroup\$ The first time I click on a requiredLogin link the code won't run (trouble shooting that now). once I click on a link the second time it will run properly. \$\endgroup\$grasshopper– grasshopper2014年11月11日 07:53:28 +00:00Commented Nov 11, 2014 at 7:53
1 Answer 1
I think I would make a state object and a user object to represent this delema.
We will make a user class to encapsulate working with the user api
var User = function(sessionStorage, authService){
var self = this,
userInfo = buildUserInfo(sessionStorage["userInfo"]);
self.isAuthentic = function(cb){
if(!hasActiveLogin) return;
//THIS is where the "doesn't work" part of your code is
//this service looks to be an async service. and you are using it in a synced way
authService.isAuthentic(userInfo._id).then(function(d){
userInfo.isAuthenticated = d.data == "true";
cb(d);
});
}
self.hasActiveLogin = function(){
var valid = userInfo != null;
valid = valid && userInfo._id;
return valid;
}
self.isAuthenticated = function(){
return self.hasActiveLogin() && userInfo.isAuthenticated;
}
self.getUserInfo = function(){
userInfo;
}
self.clearUserInfo = function(){
sessionStorage["userInfo"] = null;
}
function buildUserInfo(userInfoData){
return userInfoData ? JSON.parse(userInfoData) : null;
}
};
now the root scope can simply handle that user
This implementation is not perfect... but it does show how to use javascript to encapsulate these kinds of issues into manageable objects.
$rootScope.$on('$stateChangeStart', function(event, toState){
if(!_.has(toState.data, 'requireLogin')) return;
var user = new User($window.sessionStorage,
if(!user.hasActiveLogin()){
event.preventDefault();
$state.go('login');
}
//im not exactly sure how the service works so this peice of encapsulation
// may be over kill
if(user.isAuthenticThen(function(d)){
if(!user.isAuthenticated()){
user.clearUserInfo();
event.preventDefault();
$state.go('login');
}
$rootScope.userInfo = user.getUserInfo();
$rootScope.userAuth = user.getUserInfo().isAuthenticated || false;
}
});
-
1\$\begingroup\$ While I don't think I'll use all your code you've very much inspired me! It is a much better Idea to create a class thank you. \$\endgroup\$grasshopper– grasshopper2014年11月11日 10:08:59 +00:00Commented Nov 11, 2014 at 10:08
Explore related questions
See similar questions with these tags.