DaftMonk/generator-angular-fullstack 中未定义 getCurrentUser().role
getCurrentUser().role undefined in DaftMonk/generator-angular-fullstack
我们正在为项目使用 DaftMonk/AngularJS 全栈生成器。生成的代码包含管理用户(注册、登录、角色等)的逻辑,这很棒。但是,使用代码时会出现问题,有时会出现未定义当前用户角色的问题。
我们遇到了这个问题,因为我们想要实现一个简单的功能:在 login/signup 之后,用户应该被重定向到一个 URL,这取决于他的角色。例如,'teacher'
用户应重定向到 /teacherHome
,'student'
用户应重定向到 /studentHome
。因为 Auth.getCurrentUser().role 未定义,所以逻辑不起作用。
如何重现问题
要重现该问题,请编辑 client/app/account/login/login.controller.js
文件并添加语句以记录 Auth.getCurrentUser().role 的值,如下所示:
...
if(form.$valid) {
Auth.login({
email: $scope.user.email,
password: $scope.user.password
})
.then( function() {
// Logged in, redirect to home
console.log("Current user role: " + Auth.getCurrentUser().role);
$location.path('/');
})
.catch( function(err) {
$scope.errors.other = err.message;
});
}
};
...
在测试这段代码的时候,你会发现这个阶段用户角色是未定义的。然而,稍后,它被分配了一个值。这表明问题可能与异步 REST 调用有关。
实际上有几个相关的问题和解决它们的方法。
解决方案 1:使用提供的 Auth.isLoggedInAsync
函数
作为生成代码的一部分,Auth 模块提供了一种方法来检查登录过程是否已完成(并在完成时调用回调函数)。因此,解决此问题的一种方法是在客户端代码中使用此函数,如下所示:
if(form.$valid) {
Auth.login({
email: $scope.user.email,
password: $scope.user.password
})
.then( function() {
// Logged in, redirect to home
console.log("Current user role: " + Auth.getCurrentUser().role);
Auth.isLoggedInAsync(function(success) {
console.log("Current user role: " + Auth.getCurrentUser().role);
});
$location.path('/');
})
.catch( function(err) {
$scope.errors.other = err.message;
});
}
};
在这种情况下,您将在控制台中看到两条语句。第一个将显示 Auth.getCurrentUser().role 仍未定义。第二个将显示它现在有一个值。因此,如果您有希望在登录时执行的逻辑并且取决于用户角色(或其他用户属性),请将此逻辑放入您传递给 Auth.isLoggedInAsync()
.
的回调函数中
解决方案 2:修复 auth.service.js
中的根本原因
如果您查看 client/components/auth/auth.service.js
中的代码,您会发现异步代码存在问题。问题是 currentUser = User.get();
触发异步 HTTP 调用,并且 currentUser
没有立即设置(这是一个非阻塞调用)。由于 promise 立即 resolve,因此客户会认为登录过程已完成并且所有用户数据都可用,但实际上它仍在运行中。
在提议的修复中,承诺在传递给 User.get()
的回调函数中得到解决。
/**
* Authenticate user and save token
*
* @param {Object} user - login info
* @param {Function} callback - optional
* @return {Promise}
*/
login: function (user, callback) {
var cb = callback || angular.noop;
var deferred = $q.defer();
$http.post('/auth/local', {
email: user.email,
password: user.password
}).
/* ORIGINAL CODE -- promise is resolved too early
success(function (data) {
$cookieStore.put('token', data.token);
currentUser = User.get();
deferred.resolve(data);
return cb();
}).
*/
/* PROPOSED FIX -- promise is resolved once HTTP call has returned */
success(function (data) {
$cookieStore.put('token', data.token);
currentUser = User.get(function() {
deferred.resolve(data);
return cb();
});
}).
error(function (err) {
this.logout();
deferred.reject(err);
return cb(err);
}.bind(this));
return deferred.promise;
},
相关问题和修复
提议的代码解决了一个问题。现在可以在成功登录后将用户重定向到特定页面。但是,在注册过程之后会出现类似的问题。同样在这种情况下,Auth.getCurrentUser().role
暂时未定义(足够长的时间使重定向逻辑失败)。
在这种情况下,代码固定如下:
/**
* Create a new user
*
* @param {Object} user - user info
* @param {Function} callback - optional
* @return {Promise}
*/
createUser: function (user, callback) {
var cb = callback || angular.noop;
/* ORIGINAL CODE ---------------------
return User.save(user,
function(data) {
$cookieStore.put('token', data.token);
currentUser = User.get();
return cb(user);
},
function(err) {
this.logout();
return cb(err);
}.bind(this)).$promise;
--------------------- */
/* PROPOSED FIX --------------------- */
var deferred = $q.defer();
User.save(user,
function (data) {
$cookieStore.put('token', data.token);
currentUser = User.get(function () {
console.log('User.save(), user role: ' + currentUser.role);
deferred.resolve(data);
return cb(currentUser);
});
},
function (err) {
this.logout();
return cb(err);
deferred.reject(err);
});
return deferred.promise;
},
我们正在为项目使用 DaftMonk/AngularJS 全栈生成器。生成的代码包含管理用户(注册、登录、角色等)的逻辑,这很棒。但是,使用代码时会出现问题,有时会出现未定义当前用户角色的问题。
我们遇到了这个问题,因为我们想要实现一个简单的功能:在 login/signup 之后,用户应该被重定向到一个 URL,这取决于他的角色。例如,'teacher'
用户应重定向到 /teacherHome
,'student'
用户应重定向到 /studentHome
。因为 Auth.getCurrentUser().role 未定义,所以逻辑不起作用。
如何重现问题
要重现该问题,请编辑 client/app/account/login/login.controller.js
文件并添加语句以记录 Auth.getCurrentUser().role 的值,如下所示:
...
if(form.$valid) {
Auth.login({
email: $scope.user.email,
password: $scope.user.password
})
.then( function() {
// Logged in, redirect to home
console.log("Current user role: " + Auth.getCurrentUser().role);
$location.path('/');
})
.catch( function(err) {
$scope.errors.other = err.message;
});
}
};
...
在测试这段代码的时候,你会发现这个阶段用户角色是未定义的。然而,稍后,它被分配了一个值。这表明问题可能与异步 REST 调用有关。
实际上有几个相关的问题和解决它们的方法。
解决方案 1:使用提供的 Auth.isLoggedInAsync
函数
作为生成代码的一部分,Auth 模块提供了一种方法来检查登录过程是否已完成(并在完成时调用回调函数)。因此,解决此问题的一种方法是在客户端代码中使用此函数,如下所示:
if(form.$valid) {
Auth.login({
email: $scope.user.email,
password: $scope.user.password
})
.then( function() {
// Logged in, redirect to home
console.log("Current user role: " + Auth.getCurrentUser().role);
Auth.isLoggedInAsync(function(success) {
console.log("Current user role: " + Auth.getCurrentUser().role);
});
$location.path('/');
})
.catch( function(err) {
$scope.errors.other = err.message;
});
}
};
在这种情况下,您将在控制台中看到两条语句。第一个将显示 Auth.getCurrentUser().role 仍未定义。第二个将显示它现在有一个值。因此,如果您有希望在登录时执行的逻辑并且取决于用户角色(或其他用户属性),请将此逻辑放入您传递给 Auth.isLoggedInAsync()
.
解决方案 2:修复 auth.service.js
如果您查看 client/components/auth/auth.service.js
中的代码,您会发现异步代码存在问题。问题是 currentUser = User.get();
触发异步 HTTP 调用,并且 currentUser
没有立即设置(这是一个非阻塞调用)。由于 promise 立即 resolve,因此客户会认为登录过程已完成并且所有用户数据都可用,但实际上它仍在运行中。
在提议的修复中,承诺在传递给 User.get()
的回调函数中得到解决。
/**
* Authenticate user and save token
*
* @param {Object} user - login info
* @param {Function} callback - optional
* @return {Promise}
*/
login: function (user, callback) {
var cb = callback || angular.noop;
var deferred = $q.defer();
$http.post('/auth/local', {
email: user.email,
password: user.password
}).
/* ORIGINAL CODE -- promise is resolved too early
success(function (data) {
$cookieStore.put('token', data.token);
currentUser = User.get();
deferred.resolve(data);
return cb();
}).
*/
/* PROPOSED FIX -- promise is resolved once HTTP call has returned */
success(function (data) {
$cookieStore.put('token', data.token);
currentUser = User.get(function() {
deferred.resolve(data);
return cb();
});
}).
error(function (err) {
this.logout();
deferred.reject(err);
return cb(err);
}.bind(this));
return deferred.promise;
},
相关问题和修复
提议的代码解决了一个问题。现在可以在成功登录后将用户重定向到特定页面。但是,在注册过程之后会出现类似的问题。同样在这种情况下,Auth.getCurrentUser().role
暂时未定义(足够长的时间使重定向逻辑失败)。
在这种情况下,代码固定如下:
/**
* Create a new user
*
* @param {Object} user - user info
* @param {Function} callback - optional
* @return {Promise}
*/
createUser: function (user, callback) {
var cb = callback || angular.noop;
/* ORIGINAL CODE ---------------------
return User.save(user,
function(data) {
$cookieStore.put('token', data.token);
currentUser = User.get();
return cb(user);
},
function(err) {
this.logout();
return cb(err);
}.bind(this)).$promise;
--------------------- */
/* PROPOSED FIX --------------------- */
var deferred = $q.defer();
User.save(user,
function (data) {
$cookieStore.put('token', data.token);
currentUser = User.get(function () {
console.log('User.save(), user role: ' + currentUser.role);
deferred.resolve(data);
return cb(currentUser);
});
},
function (err) {
this.logout();
return cb(err);
deferred.reject(err);
});
return deferred.promise;
},