Here is my code with the relevant parts bolded:
authorization.js
angular .module('mean-starter') .run(run); function run($rootScope, Auth, $state) { $rootScope.$on('$stateChangeStart', function(event, toState, toParams) { if (typeof toState.authenticate !== 'undefined') { var currentUser = Auth.getCurrentUser(); while (!currentUser._id) {} var isAdmin = currentUser.role === 'admin'; var isAuthorized = currentUser._id.toString() === toParams.id; if (!Auth.isLoggedIn()) { event.preventDefault(); alert('Must be logged in to access this route.'); $state.go('login'); } else if (toState.authenticate.authorized) { if (!isAdmin && !isAuthorized) { event.preventDefault(); alert('You are not authorized to access that route.'); } } else if (toState.authenticate.isAdmin) { if (!isAdmin) { event.preventDefault(); alert('You must be an admin to access this route.'); } } } }); }
auth.factory.js
angular .module('mean-starter') .factory('Auth', function($http, $state, $window, $cookies) { console.log('factory cb'); var currentUser = {}; if ($cookies.get('userId')) { console.log('userId'); $http .get('/current-user') .success(function(data) { console.log('success'); angular.copy(data, currentUser); }) .error(function() { console.log('Problem getting the current user.'); }); } return { signup: function(user) { return $http.post('/users', user) .success(function(data, status, headers, config) { angular.copy(data, currentUser); $cookies.put('userId', data._id); $window.location.href = '/'; }); }, login: function(user) { return $http .post('/login', user) .success(function(data) { angular.copy(data, currentUser); $cookies.put('userId', data._id); $window.location.href = '/'; }); }, logout: function() { $http .get('/logout') .success(function() { angular.copy({}, currentUser); $cookies.remove('userId'); $window.location.href = '/'; }) .error(function() { console.log('Problem logging out.'); }); }, getCurrentUser: function() { return currentUser; }, isLoggedIn: function() { return !!currentUser._id; } }; });
My problem is that without the while
loop, I get this error:
Cannot read property 'toString' of undefined
It's referring to currentUser._id
being undefined
and me trying to call toString
on it. My understanding is that Auth.getCurrentUser()
initially returns a reference to {}
. Then the assignment statement assigns {}
to currentUser
, and the code proceeds. When the response comes back, it should update {}
, and thus should "update" currentUser
in the sense that currentUser
is pointing to an updated object.
If that were true, my problem would be understandable, because it's trying to do currentUser._id.toString()
before the response comes back. So what I tried to do is put that while
loop in there to essentially pause the execution until the response comes back. But the while
loop is running infinitely! Shouldn't the response eventually come back, update currentUser
, and when it does, !currentUser._id
should be false
, and the loop should break?
First factory cb
is logged out. Then userId
is logged out. So far so good. But then the infinite loop kicks in and success
never gets logged out. Isn't the request supposed to be asynchronous? How could the while
loop stop it? What's going on here?
There isn't a problem with the call. Without the while
loop it hits the success callback and logs success
. Additionally, if I console.dir(currentUser)
in authorization.js
it gives me the user, but if I console.log(currentUser)
, it gives me an empty object. Not sure why that is.
while
loop isn't pausing execution, then what's the problem? – Adam Zernerconsole.dir(currentUser)
works. If it passed{}
by value,currentUser
would never get updated. It also works in other parts of my code. – Adam Zerner