Angular 13 api 调用中未定义响应模型参数

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

我正在 Angular 13/TypeScript 4.4.4 中使用 httpclient 进行 POST API 调用以进行用户身份验证。我可以检查响应模型内容,看起来没问题,但如果我访问模型的属性,它是未定义的。

这是响应模型:

import { UserAccountStatus } from "./Enums";

export interface AuthResponseModel {
    UserLoginId: number;
    AccountStatus: UserAccountStatus;
}

这里是服务 POST 调用:

import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Injectable, Inject } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { AuthResponseModel } from '../shared/AuthResponseModel';
import { LoginModel } from '../shared/LoginModel';

const httpOptions = {
  headers: new HttpHeaders({
      'Content-Type': 'application/json'
  })
}

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  constructor( private http: HttpClient ) { }

  private get APIUrl(): string {
    return this.token;
  }

  Login( username: string, password: string ): Observable<AuthResponseModel> {
    const url: string = 'https://test.com/api/Auth/Login';

    const loginModel: LoginModel = {
      Username : username,
      Password : password
    };

    return this.http.post<LoginModel>( url, loginModel, httpOptions )
      .pipe(
        catchError( this.errorHandler ) );
  }

  private errorHandler( error: HttpErrorResponse ): Observable<any> {
    console.error('Error occured!');
    return throwError( () => error );
  }
}

这是我的登录表单,其中使用了该服务:

import { OnInit, Input, Component, Output, EventEmitter } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { lastValueFrom } from 'rxjs';
import { AuthService } from '../services/auth.service';
import { AuthResponseModel } from '../shared/AuthResponseModel';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  loginForm!: FormGroup;
  authResp?: AuthResponseModel;

  constructor(private authSrv: AuthService) { }

  async submit() {
    if ( this.loginForm.valid ) {
      const resp$ = this.authSrv.Login( this.loginForm.value.username, this.loginForm.value.password );
      this.authResp = await lastValueFrom( resp$ );
      
      if ( this.authResp ) {
        const id: number = this.authResp.UserLoginId // <- undefined
        const dbg: string = JSON.stringify( this.authResp );
        console.log(dbg); // <- ok with the correct value (...UserLoginId: 3)
      }
    }
  }

  ngOnInit(): void {
    this.loginForm = new FormGroup({
      username: new FormControl(''),
      password: new FormControl(''),
    });
  }
}

我在这里缺少什么?有地图吗?

这是 dbg 输出:

{"userLoginId":3,"accountStatus":5}

angular typescript rxjs angular-httpclient
3个回答
0
投票

服务器响应

userLoginId
(小写
u
)和
accountStatus
(小写
a
),因此
this.authResp.UserLoginId
未定义。

您的型号应该是

export interface AuthResponseModel {
    userLoginId: number;
    accountStatus: UserAccountStatus;
}

0
投票

终于解决了这个问题。这是由于响应模型中的属性名称造成的。我使用的是 asp.net core web api,属性名称中第一个字符为大写,这里也分别使用 Angular 和 TypeScript。我注意到 stringyfied json 第一个字符是小写的。所以我改变了角度部分的模型名称:

export interface AuthResponseModel {
  userLoginId: number;
  accountStatus: UserAccountStatus;
}

通过此更正,它正在工作。


-1
投票

在我看来,您实际上并没有等待从

this.authSrv.Login
返回。

  async login( username: string, password: string ): Observable<AuthResponseModel> {
    const url: string = 'https://test.com/api/Auth/Login';

    const loginModel: LoginModel = {
      Username : username,
      Password : password
    };

   await return this.http.post<LoginModel>( url, loginModel, httpOptions )
      .pipe(
        catchError( this.errorHandler ) );
  }


  async submit() {
    if ( this.loginForm.valid ) {
      const resp$ = await this.authSrv.Login( this.loginForm.value.username, this.loginForm.value.password );
      this.authResp = await lastValueFrom( resp$ );
      
      if ( this.authResp ) {
        const id: number = this.authResp.UserLoginId // <- undefined,respectively 0
        const dbg: string = JSON.stringify( this.authResp );
        console.log(dbg); // <- ok with the correct value (...UserLoginId: 3)
      }
    }

人们也倾向于保留以小写开头的驼峰命名法,所以我将 Login 重命名为 login。

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