我有一个加载用户数据的组件,它应该能够处理通过url直接访问的问题,我的想法是在路由器中实现一个resolver服务,当通过应用程序的路由访问组件时,它已经工作正常了。
ERROR Error: "Uncaught (in promise).TypeError: this.userService: 类型错误:this.userService.getCurrentUser()未定义。
刷新时,似乎userService的初始化速度不够快。
这是解析器服务。
@Injectable({
providedIn: 'root'
})
export class UserResolverService {
constructor(private userService: UserService, private authService: AuthService, private router:Router) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<User> | Observable<never> {
let id = route.paramMap.get('id');
//return this.authService.checkToken().subscribe(res => {
if(this.authService.checkToken()){
return this.userService.getCurrentUser().pipe(take(1), mergeMap(user => {
if(user){
return of(user);
} else {
this.router.navigate['/login'];
return EMPTY;
}
}));
} else {
this.router.navigate['/login'];
return EMPTY;
}
}
}
这是调用的UserService方法。
getCurrentUser(): Observable<User>{
if(this.currentUser.value != null){
return this.currentUser.asObservable().pipe(filter(user => user != null));
} else {
this.setCurrentUser().subscribe(res => {
return this.currentUser.asObservable().pipe(filter(user => user != null));
})
}
setCurrentUser()方法get调用后台的凭证来检索用户数据。
Component的contructor,刷新时应该可以加载其数据,包含以下内容。
this.route.data.subscribe((data: {user: User}) => {
this.user = data.user;
this.initialDialogWindows();
this.initialViewGuidingVariables();
});
EDIT:
我把它改成了Aakash Garg的建议方案。现在,ngOnit()方法只接收未定义,解析器似乎没有等待承诺。除了 "我在这里吗?"之外,其他的控制台日志都没有被执行。
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<User> {
let id = route.paramMap.get('id');
//return this.authService.checkToken().subscribe(res => {
if(this.authService.checkToken()){
console.log("am I even here?");
this.userService.getCurrentUserPromise().then(user => {
console.log("resolved user:" + user);
if(user){
return of(user);
} else {
console.log("navigating to login");
this.router.navigate['/login'];
return EMPTY;
}
});
} else {
console.log("navigating to login, because there is no token");
this.router.navigate['/login'];
return EMPTY;
}
}
问题不在于服务初始化,而在于你的getCurrentUser方法的写法,因为在currentUser.value为null的情况下,它不会等待订阅完成而返回undefined,这就是async任务的工作方式。
async getCurrentUser(): Promise<User>{
if(this.currentUser.value != null){
return this.currentUser.asObservable().pipe(filter(user => user != null)).toPromise();
} else {
await this.setCurrentUser().toPromise();
return await this.currentUser.asObservable().pipe(filter(user => user != null)).toPromise();
}
}
并将你的解析器改为:-。
@Injectable({
providedIn: 'root'
})
export class UserResolverService {
constructor(private userService: UserService, private authService: AuthService, private router:Router) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<User> | Observable<never> {
let id = route.paramMap.get('id');
//return this.authService.checkToken().subscribe(res => {
if(this.authService.checkToken()){
this.userService.getCurrentUser().then(user => {
if(user){
return of(user);
} else {
this.router.navigate['/login'];
return EMPTY;
}
});
} else {
this.router.navigate['/login'];
return EMPTY;
}
}
}