我正在尝试授权用户查看某些路由器路径。
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.userService.isAdmin() || this.userService.isEmployee()
}
用户服务方法是同步的。用户服务是单例,从后端加载用户数据。当用户通过正常的应用程序流程时,这不是问题。但是当用户尝试直接进入受保护的路径路径时,可能无法及时加载用户服务信息,从而导致错误
EXCEPTION: Uncaught (in promise): TypeError: Cannot read property 'roleId' of undefined
TypeError: Cannot read property 'roleId' of undefined
这是用户服务代码
@Injectable()
export class UserService {
public $user;
public loggedUser;
constructor(private loginService: ResourceLoginService) {
this.$user = this.loginService.get().$observable;
this.$user.subscribe(response => {
this.loggedUser = response;
});
}
isAdmin(): boolean {
return this.loggedUser.roleId === 1;
}
我基本上想订阅$user,如果尚未完成,则异步调用方法,或者在CanActive守卫中完成时调用方法。处理这个问题的正确方法是什么?
您可以删除user$
的订阅并写入:
isAdmin(): boolean {
return this.user$
.map(user => user.roleId === 1);
}
对于canActivate
,您可以返回:Observable<boolean> | Promise<boolean> | boolean
,它将在解析路由权限之前等待承诺/可观察
解决方案是函数应该返回一致的类型,无论如何。如果其中一种情况是同步的,而另一个异步函数需要从同步源返回可观察到的异步。
export class UserService {
public $user;
public loggedUser;
constructor(private loginService: ResourceLoginService) {
this.$user = this.loginService.get().$observable;
this.$user.subscribe(response => this.loggedUser = response);
}
isAdmin(): Observable<boolean> {
if (this.loggedUser) {
return Observable.of(this.loggedUser.roleId === 1);
} else
return this.$user
.map(user => user.roleId === 1);
}