如何在Word中将http请求响应映射到我定义的对象

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

我开始了解Angular,TypeScript和RxJS。我有一个返回JSON的http请求。在这个JSON中,我需要构建定义对象的数据。让我们说,我的目标是:

export class RegularUser {
    constructor(
        public id: number,
        public firstName: string,
        public lastName: string,
        public token: string
    ) {}
}

现在,我正在向某个API发送请求,该API以这种格式返回数据:

{
    success: boolean,
    uid: number,
    first_name: string,
    last_name: string,
    cid: number,
    rights: number[]
    token: string
}

我有HttpClient服务,所以我想我会这样做:

this.httpClient.get(
    'http://api.example.com/api/get_user'
).pipe(
    tap((receivedData: Response) => console.log(receivedData)),
    map((receivedData: Response) => {
        return new RegularUser(
            receivedData.uid, 
            receivedData.first_name, 
            receivedData.last_name, 
            receivedData.token);
    })
);

但对于TypeScript,receivedData对象没有上面列出的参数。我是否必须为API响应创建一个接口,然后将其映射到我的RegularUser对象?

angular typescript interface rxjs
3个回答
1
投票

您可以为type指定get(),例如界面。为什么中间/附加接口可能需要在你的情况中分离关注点,因为类型的get()不会新建一个类RegularUser的实例。可以使用您希望从服务器响应中创建的属性创建中间/附加接口,该响应将用于创建最终类的实例:

interface Foo {
  uid: number,
  first_name: string,
  last_name: string,
  token: string
}

this.httpClient.get<Foo>(
    'http://api.example.com/api/get_user'
).pipe(
    tap((receivedData: Foo) => console.log(receivedData)),
    map((receivedData: Foo) => {
        return new RegularUser(
            receivedData.uid, 
            receivedData.first_name, 
            receivedData.last_name, 
            receivedData.token);
    })
);

如果您不需要新建一个类RegularUser的实际实例,那么将它作为具有属性的接口或类就足够了:

this.httpClient.get<RegularUser>(
    'http://api.example.com/api/get_user'
).pipe(
    tap((receivedData: RegularUser) => console.log(receivedData))
);

希望这有帮助!


1
投票

而不是构造函数,使用接口,这是一个更好的选择。因此,IDE可以使用语言服务启用代码自动完成,并且可以避免错误的属性命名。

export interface RegularUser {
    success: boolean;
    uid: number;
    first_name: string;
    last_name: string;
    cid: number;
    rights: number[];
    token: string;
}

在服务中:

this.httpClient.get<RegularUser>(
    'http://api.example.com/api/get_user'
).pipe(
    tap((receivedData: RegularUser) => console.log(receivedData))
);

1
投票

您可以使用以下命令创建自己的Response界面:

export interface MyResponse {
  success: boolean,
  uid: number,
  first_name: string,
  last_name: string,
  cid: number,
  rights: number[]
  token: string
}

然后将其导入您的服务:

import { MyResponse } from '../some/path/filename.ts'; 

但您也可以将它包含在您的服务中,因此您可以跳过'export'

您可以像使用当前的Response界面一样使用它:

(receivedData: MyResponse)

注意:您可以为其指定任何名称(使用TitleCase保持一致性)。您也可以使用Angular已经使用的名称,然后将被覆盖,但不建议这样做。看评论。


您可能必须使一些属性可选(?:),否则您可能会得到一条红线,表示如果不是全部使用了“某些属性丢失”:

...
success?: boolean,
...

或者,您可以通过键入any来删除警告,但不建议这样做:

(receivedData: any)
© www.soinside.com 2019 - 2024. All rights reserved.