ERROR TypeError: Cannot read properties of undefined (reading 'message') in Angular Login

ERROR TypeError: Cannot read properties of undefined (reading 'message') in Angular Login

在我的 Angular 13 中,我有这个代码:

JSON 来自 ASP.NET Core Web 的响应 API:

{
   "code": 200,
   "error": false,
   "message": "Logged In Successful",
   "results": {
       "token": "thisismytoken...",
       "user": {
           "id": 1,
           "username": "Ashwel",
          },
       "roles": [
           "SuperAdmin"
       ]
   }
}

ANGULAR

user.ts:

export interface IResponse<T> {
  message: string;
  error: boolean;
  code: number;
  results: T;
}

export interface IUser 
{
  username?: string;
  token?: string;
  roles?: string[];
}

auth.service:

export class AuthService {
  baseUrl = environment.apiUrl;
  private currentUserSource = new ReplaySubject<IUser | null>(1);
  currentUser$ = this.currentUserSource.asObservable();

  constructor(private http: HttpClient, private router: Router) { }
  login(model: any){
    return this.http.post(this.baseUrl+'auth/login', model).pipe(
      map((res:IUser)=>{
        const user = res;
        if(user){
          this.setCurrentUser(user);
        }
      })
    )
  }

  setCurrentUser(user: IUser){
    if(user && user.token){
      user.roles = [];
      const roles = this.getDecodedToken(user.token).role;
      Array.isArray(roles) ? user.roles = roles : user.roles.push(roles);
      localStorage.setItem('user', JSON.stringify(user));
      this.currentUserSource.next(user);
    }
  }

  getDecodedToken(token: string) {
    return JSON.parse(atob(token.split('.')[1]));
  }
}

auth.component:

export class AuthComponent implements OnInit {
  loginForm!: FormGroup;
  user!: IUser | null;

  constructor(
   private authService: AuthService,
   private router: Router,
   private toastr: ToastrService
   ) {
   this.authService.currentUser$.pipe(take(1)).subscribe(user=> this.user = user);
 }

myForm() {
  this.loginForm = new FormGroup({
    UserName: new FormControl('', Validators.required),
    Password: new FormControl('', [Validators.required])
  })
}

login(){
  this.authService.login(this.loginForm.value).subscribe({
    next: (res: any) => {
      console.log(res);
      this.toastr.success(res.message);
      this.router.navigateByUrl('dashboard');
    },
    error: (error) => {
      this.toastr.error(error.message);
    }
  })
 }
}

这是流程 auth.component -> auth.service -> user.ts:

我打算做的是,当用户提交登录时:

  1. 令牌、用户名和角色存储在 localStorage
  2. 登录成功后显示信息:登录成功
  3. 它重定向到仪表板

但不是所有这些,我在检查 -> 控制台中得到了这个错误:

ERROR TypeError: Cannot read properties of undefined (reading 'message')

当我在 auth.service 中执行 console.log(res) 时,我得到了未定义。

如何解决此错误?

谢谢

AuthService.login 方法中的 map pipe 似乎应该 return 数据

login(model: any){
  return this.http.post(this.baseUrl+'auth/login', model).pipe(
    map((res:IUser) => {
      const user = res;
      if(user){
        this.setCurrentUser(user);
      }
      return res; // <- here
    })
  )
}

管道文档https://www.learnrxjs.io/learn-rxjs/operators/transformation/map

我发现你的 AuthService.login 方法有两个错误:

  • 根据您发布的 JSON,您的回复标签为 IUser,它应该是 IResponse<IUser>>
  • 您正在使用 map 运算符触发副作用。 map 用于对发出的值应用转换,因此 map 函数应该 return 转换值。要触发副作用,您应该使用 tap.

所以你应该修改方法如下

login(model: any){
  return this.http.post<IResponse<IUser>>(this.baseUrl+'auth/login', model).pipe(
    tap((response) => {
      const user = response.results;
      if(user){
        this.setCurrentUser(user);
      }
    })
  )
}

干杯