0

我有一个加载用户数据的组件,应该能够处理通过 url 直接访问。我的想法是在路由器中实现一个解析器服务,当通过应用程序的路由访问组件时,它已经可以正常工作了。但是如果我在 url 上刷新应用程序,解析器服务会抛出以下错误:

错误错误:“未捕获(承诺):TypeError: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 使用凭据调用后端以检索用户数据。

组件的构造函数,应该能够在刷新时加载其数据,包含以下内容:

this.route.data.subscribe((data: {user: User}) => {
  this.user = data.user;
  this.initialDialogWindows();
  this.initialViewGuidingVariables();
});

编辑:

我将其更改为 Aakash Garg 的建议解决方案。现在 ngOnit() 方法只接收 undefined 并且解析器似乎不等待承诺。“我在这里吗?”旁边的控制台日志都没有。被执行。

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;
}

 }
4

1 回答 1

0

问题不在于服务初始化,而在于您的 getCurrentUser 方法的编写方式。因为在 currentUser.value 为 null 的情况下,它不会等待订阅完成并返回 undefined。这就是异步任务的工作方式。将您的 getCurrentUser 方法更改为:-

    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;
}

 }

 }
于 2020-06-16T19:07:44.927 回答