【问题标题】:How to query REST API using strict typecasting如何使用严格的类型转换查询 REST API
【发布时间】:2019-06-07 08:47:28
【问题描述】:

我无法解析 API 的输出(项目数组在属性 results 内)。因为 TS 说 results 不是 Project 类的属性。

项目类:

export class Project {
  project_id: string;
  project_name: string;
  project_code: string;
  project_lead: string;
  project_cost_center: number;
  project_number: string;
  budget: number;
  team: string;
  provision: boolean;
  project_groups: any;
  project_networks: any;
  applications: any;
  project_environments: any;
  subscription: string;
  created_at: string;
}

API 响应示例:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "url": "http://localhost:8000/api/v1/projects/COA/",
            "project_id": 57,
            "project_name": "Compliance Application",
            "project_code": "COA",
            "project_lead": "John Doe",
            "project_cost_center": "9005",
            "project_number": "900512I320",
            "budget": 600.0,
            "team": "http://localhost:8000/api/v1/teams/TTA/",
            "provision": true,
            "project_groups": [],
            "project_networks": [
                "http://localhost:8000/api/v1/ip-network/23/"
            ],
            "applications": [
                "http://localhost:8000/api/v1/applications/COA/"
            ],
            "project_environments": [
                "http://localhost:8000/api/v1/environments/8/",
                "http://localhost:8000/api/v1/environments/7/"
            ],
            "subscription": "http://localhost:8000/api/v1/subscriptions/128a4bb5-604d-11e9-86ee-88e9fe8080e6/",
            "created_at": "2019-04-16T13:37:05.293000Z"
        }
    ]
}

这是我正在使用的:

Angular CLI: 8.0.1
Node: 12.4.0
OS: darwin x64
Angular: 8.0.0
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.800.1
@angular-devkit/build-angular     0.800.1
@angular-devkit/build-optimizer   0.800.1
@angular-devkit/build-webpack     0.800.1
@angular-devkit/core              8.0.1
@angular-devkit/schematics        8.0.1
@angular/cli                      8.0.1
@ngtools/webpack                  8.0.1
@schematics/angular               8.0.1
@schematics/update                0.800.1
rxjs                              6.4.0
typescript                        3.4.5
webpack                           4.30.0

我的初始函数如下所示:

// HttpClient API get() method => Fetch project list
  getProjects(): Observable<Project[]> {
    return this.http.get<Project[]>(this.apiURL + '/projects')
      .pipe(
        retry(1),
        catchError(this.handleError)
      )
  }

当然,我应该使用 RxJS 的 map 和来自 GET 操作的数据来迭代 results 并产生对象数组。

如果我这样做

// HttpClient API get() method => Fetch project list
  getProjects(): Observable<Project[]> {
    return this.http.get<Project[]>(this.apiURL + '/projects')
      .pipe(
        map(data => data.json().results),
        retry(1),
        catchError(this.handleError)
      )
  }

然后我收到一条消息说类Project 没有属性json()。这是因为我将.get() 方法类型转换为Project[]?如果是这样,我应该如何进行类型转换?

我希望能正确地进行类型转换,但我对 Angular 还很陌生,文档没有帮助。

【问题讨论】:

  • HttpClient.get() 自动应用 res.json() 并返回。您不再需要自己调用此函数。
  • 即便如此,data.results 也不起作用,因为我相信它会将get() 的输出视为Project[] 类型。我应该将get() 转换成别的东西吗?
  • 您能展示您的Project 定义吗?是interface 还是class
  • .json() 在类型 HttpResponse angular.io/api/common/http/HttpResponse 上确实不存在。
  • 我更新了问题以显示项目类和 API 响应格式。

标签: json angular rest rxjs observable


【解决方案1】:

API 不返回 Project 数组,您有 2 个解决方案可以解决您的问题:

第一个解决方案,不要使用类型化响应:

getProjects(): Observable<Project[]> {
  return this.http.get(this.apiURL + '/projects')
    .pipe(
      map(data => data.results),
      retry(1),
      catchError(this.handleError)
    );
}

第二种解决方案,使用类型化响应

现在 HttpClient.get() 返回一个类型化 HttpResponse 的 Observable 而不仅仅是 JSON 数据。

export interface ApiProjectResponse {   
  count: number;
  next: any;
  previous: any;
  results: Project[];
}

getProjects(): Observable<Project[]> {
  // HTTP GET /projects returns an ApiProjectResponse
  return this.http.get<ApiProjectResponse>(this.apiURL + '/projects')
    .pipe(
      map(data => data.results),
      retry(1),
      catchError(this.handleError)
    );
}

【讨论】:

    【解决方案2】:

    问题可能是您的 API 没有返回项目数组。它的结构可能不同(类似于APIResponse)。但是在您的方法中,您想要返回一个项目数组。

    如果问题是这样,那么,您应该编写类似这样的代码。

    // HttpClient API get() method => Fetch project list
      getProjects(): Observable<Project[]> {
        return this.http.get<APIResponse>(this.apiURL + '/projects')
          .pipe(
            map(data => data.results),
            retry(1),
            catchError(this.handleError)
          )
      }
    

    你的 APIResponse 类应该是这样的。

    export class APIResponse {   
      count: number;
      next: any;
      previous: any;  
      results: Project[];
    }
    

    【讨论】:

    • 不,你不知道他的Project 长什么样。你只是在没有头绪的情况下说话。这没有添加任何内容。
    • @Bjorn'Bjeaurn'S - 据我了解,他的 API 没有返回数组,但他想返回一个数组。
    • 如果是这样,这不是一个真正的 Angular 问题,是吗?但即使在这种情况下,我们也需要来自他的服务器的示例响应,然后才能开始给出正确的答案,而不是猜测或假设。
    • 其实响应JSON中属性results有一个project数组。
    • 我将此答案评为正确答案,因为我想要一种类型化的方法。请注意,APIResponse 的类定义不正确,因为您使用的是逗号而不是分号。
    【解决方案3】:

    如果您期望得到Projects 的列表,那么您的数据中已经有了它,因为您的typedProject[],这会导致array of Project

    使用您的数据,您可以执行data.length 之类的操作,以查看您有多少Project 的记录。这是基本的数组操作。

    Array 上没有 .results。您只需 console.log(data) 即可查看整个 Array 并使用它。 data.forEach() 遍历阵列等内部的每个 Project。您可以将其传递给*ngFor="let project of projects",它会为您遍历Array

    【讨论】:

      猜你喜欢
      • 2017-05-19
      • 1970-01-01
      • 1970-01-01
      • 2013-06-29
      • 1970-01-01
      • 1970-01-01
      • 2020-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多