【问题标题】:Angular 7 - HttpClient "Property 'success' does not exist on type Object"Angular 7 - HttpClient“对象类型上不存在属性'成功'”
【发布时间】:2019-05-18 08:12:09
【问题描述】:

当有人注册时,我会将信息发布到我的后端。成功注册用户后,我收到 {success: true, msg: "User registered"} 的 json 响应。我的问题是当我尝试执行 if 语句来检查成功是否设置为 true 时。

这是我的代码不起作用:

    // Register User
    this.apiService.registerUser(user).subscribe(data => {
      if(data.success) {
        this.flashMessage.show('Registration successful', { cssClass: 'alert-success', timeout: 3200 });
      } else {
        this.flashMessage.show('Registration failed', { cssClass: 'alert-danger', timeout: 3200 });
      }
    });

我能够控制台记录数据的响应,并返回:

{success: true, msg: "User registered"}

这是我的 ApiService 中的代码:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { User } from '../models/User';

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  private baseUri: string = 'http://localhost:5000/api';
  private headers = new HttpHeaders().set('Content-Type', 'application/json');

  constructor(private http: HttpClient) { }

  registerUser(user: User) {
    return this.http.post(this.baseUri + '/register', user, { headers: this.headers });
  }
}

这是我的注册组件中的代码:

onRegisterSubmit() {
    const user: User = {
      firstName: this.firstName,
      lastName: this.lastName,
      email: this.email,
      username: this.username,
      password: this.password
    };

// Register User
    this.apiService.registerUser(user).subscribe(data => {
      console.log(data);
    });

  }

Screenshot of error from ng serve

我对使用 Angular 还是很陌生,更不用说后端了,所以如果你能解释为什么会发生这个错误,我将不胜感激。

如果您需要更多信息,请告诉我。

【问题讨论】:

  • 你能发布实际的错误堆栈吗?它发生在运行时还是编译时?
  • 是success 是从POST 返回的结果,还是您尝试访问HttpResponse 本身的某些内容?
  • success 是从 POST 返回的结果。这是控制台错误的截图i.stack.imgur.com/9rCBR.png
  • 我通过将res 的类型识别为any 来解决此问题。所以应该是这样的:this.http.post('http://localhost:3000/api', obj).subscribe((res:any) => { console.log(res.success) }

标签: angular typescript


【解决方案1】:

属性“成功”不存在于类型“对象”上。创建代码为:

// Register User
this.apiService.registerUser(user).subscribe( (data) => {
    if(data['success']) {
        this.flashMessage.show('Registration successful', { cssClass: 'alert-success', timeout: 3200 });
    } else {
        this.flashMessage.show('Registration failed', { cssClass: 'alert-danger', timeout: 3200 });
    }
});

此更改纠正了我在 Angular ts 文件中的错误。

【讨论】:

    【解决方案2】:

    这是一个编译器错误,这也是 Typescript 很棒的原因之一!

    您的registerUser 方法的返回类型隐含为Object(或{}),因为这是http.post 返回的内容。 http.post 接受一个通用参数来定义将在响应的body 中返回的内容。如果没有该参数,它将返回类型{}(因为,如果没有某种定义,JSON 只是一个未知的Object)......并且success 的键在{} 上不存在。

    假设您有一个充实的响应对象,只需强烈键入它:

    interface UserPostResponse {
      success: boolean
    }
    
    ...
    
      registerUser(user: User): Observable<UserPostResponse> {
        return this.http.post<UserPostResponse>(this.baseUri + '/register', user, { headers: this.headers });
      }
    

    相反,如果您想要HttpRequest 本身而不是正文,您只需告诉HttpClient 要观察响应的哪一部分:

      registerUser(user: User): Observable<HttpResponse<object>> {
        return this.http.post(this.baseUri + '/register', user, { headers: this.headers }, observe: 'response');
      }
    

    ...而HttpResponse 有status、statusText、body 等。

    【讨论】:

    【解决方案3】:

    错误 TS2339:类型“Y”上不存在属性“x”

    是编译时错误。 Angular HttpClient 有各种post 函数声明,其中之一是:

    post<T>(url: string, body: any | null, options?: { ... }): Observable<T>;
    

    您可以在其中强烈键入您的回复类型。您可以引入响应接口并使用它:

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpHeaders } from '@angular/common/http';
    
    import { Observable } from 'rxjs';
    
    import { User } from '../models/User';
    
    export interface RegisterResponse {
      success: boolean;
      msg: string;
    }
    
    @Injectable({
      providedIn: 'root'
    })
    export class ApiService {
      private baseUri: string = 'http://localhost:5000/api';
      private headers = new HttpHeaders().set('Content-Type', 'application/json');
    
      constructor(private http: HttpClient) { }
    
      registerUser(user: User): Observable<RegisterResponse> {
        return this.http.post<RegisterResponse>(this.baseUri + '/register', user, { headers: this.headers });
      }
    }
    

    那么从 TypeScript 编译器的角度来看,您将是类型安全的。

    否则,匹配的声明将是:

    post(url: string, body: any | null, options?: { ... }): Observable<Object>;
    

    其中Object 没有声明属性succuess,因此会导致该错误。

    另一种避免它的方法是使用as any 或any,请参阅下面的参考资料。但通常情况下,您会希望 TypeScript 跟踪您的类型。

    TypeScript 是强类型的,这意味着它会尝试确保您使用的数据类型实际上是正确的。所以如果你试图引用一些没有已知类型的属性,它会报错。

    您还可以看到:

    等了解此事。

    【讨论】:

    猜你喜欢
    • 2019-08-14
    • 2022-07-23
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 2020-10-31
    • 1970-01-01
    相关资源
    最近更新 更多