【问题标题】:Observable from JSON response可从 JSON 响应中观察到
【发布时间】:2020-01-02 03:25:20
【问题描述】:

我正在学习 Angular(第 8 版)并坚持使用 RxJS。准确地说,我无法从 Observable 中读取特定的键。

这是我的用户界面:

export interface User {
  id: Number;
  email: String;
  first_name: String;
  last_name: String;
  avatar: String;
}

然后在 users.service.ts 中,我有一个名为 getUsers() 的方法,它从 API 调用 (https://reqres.in/api/users) 接收数据。响应 JSON 如下所示:

{
page: 1,
per_page: 6,
total: 12,
total_pages: 2,
data: [
{
id: 1,
email: "george.bluth@reqres.in",
first_name: "George",
last_name: "Bluth",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg"
},
{
id: 2,
email: "janet.weaver@reqres.in",
first_name: "Janet",
last_name: "Weaver",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"
},
{
id: 3,
email: "emma.wong@reqres.in",
first_name: "Emma",
last_name: "Wong",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg"
},
{
id: 4,
email: "eve.holt@reqres.in",
first_name: "Eve",
last_name: "Holt",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"
},
{
id: 5,
email: "charles.morris@reqres.in",
first_name: "Charles",
last_name: "Morris",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"
},
{
id: 6,
email: "tracey.ramos@reqres.in",
first_name: "Tracey",
last_name: "Ramos",
avatar: "https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"
}
]
}

users.service.ts 文件如下所示:

import { Injectable } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Observable } from "rxjs";

import { User } from "../models/user";

const httpOptions = {
  headers: new HttpHeaders({ "Content-Type": "applicaiton/json" })
};

@Injectable({
  providedIn: "root"
})
export class UsersService {
  private getUsersUrl: string = "https://reqres.in/api/users";
  constructor(private http: HttpClient) {}

  // We have casted the observable into an array of type User
  getUsers(): Observable<User[]> {
    return this.http.get<User[]>(this.getUsersUrl);
  }
}

Observable 返回整个 JSON 响应。我试图从我的组件中的这个响应中读取用户数组。

ngOnInit() {
    this.loaded = false;
    setTimeout(() => {
      this.usersService.getUsers().subscribe(cards => {
        // How do I read the "data" key in cards?
        this.users = cards.data; /* Error */
        this.loaded = true;
        console.log(this.users);
      });
    }, 2000);
  }

得到以下错误:

src/app/components/main/main.component.ts(21,28) 中的错误:错误 TS2339:“用户[]”类型上不存在属性“数据”。 [有意义,因为它没有在用户界面中定义]

如果我将this.users = cards.data; 更改为this.users = cards;,然后执行console.log,我会从上面看到整个JSON 响应。我正在尝试在我的 UI 上显示用户列表。

请指教。

【问题讨论】:

  • 错误来自打字稿,因为getUsers(): Observable&lt;User[]&gt; 没有返回用户数组
  • this.http.get

标签: angular rxjs observable


【解决方案1】:

您的 getUsers() 函数返回一个“用户”类型的数组,该类型没有“数据”属性。这就是您收到错误的原因。

基本上您的 json 结构与您尝试使用的类型的结构不匹配。

要解决这个问题,可以创建一个新类型,例如:

export interface Page {
  page: number,
  per_page: number,
  total: number,
  total_pages: number,
  data: User[]
}

然后从您的服务中返回:

 getUsers(): Observable<User[]> {
    return this.http.get<Page>(this.getUsersUrl);
  }

现在您应该可以访问您订阅中的cards.data了。

【讨论】:

  • 这对我不起作用。如果响应 JSON 中有许多我不需要的字段怎么办。
【解决方案2】:

如果你想返回一个 User[] 的 observable,你可以使用 map 操作符返回数据:

getUsers(): Observable<User[]> {
  return this.http.get(this.getUsersUrl).pipe(map((result:any)=>result.data));
}

并订阅 observable,例如:

this.usersService.getUsers().subscribe(users=> {
    this.users = users;
    this.loaded = true;
    console.log(this.users);
  });

【讨论】:

  • 这可行,但在 Angular 终端上出现错误 [错误在 src/app/services/users.service.ts(25,70):错误 TS2339:类型上不存在属性“数据” '目的']。是否有某种异步管道?
  • 我的意思是,是因为数据是异步推送的吗?
  • return this.http.get(this.getUsersUrl).pipe(map((result:any)=&gt;result.data)); 看到我们将结果“投射”为任意
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-05
  • 2012-07-31
  • 2020-01-17
相关资源
最近更新 更多