在Angular 9应用中,当刷新时,服务未定义,并在路由中使用解析器。

问题描述 投票:0回答:1

我有一个加载用户数据的组件,它应该能够处理通过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;
}

 }
angular typescript angular-resolver
1个回答
0
投票

问题不在于服务初始化,而在于你的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;
}

 }

 }
© www.soinside.com 2019 - 2024. All rights reserved.