接口不会填充元素数组

时间:2018-09-30 14:53:20

标签: arrays json angular typescript

我在Angular中发出以下请求,并将响应保存在变量中:

conversations: Conversation[];

// ChatService
getConversations() {
    return this.http.get<Conversation[]>('/chat/conversations');
}

this.chatService.getConversations().subscribe(
    (response: Conversation[]) => this.conversations = response
);

这是来自服务器的JSON数据:

[  
   {  
      "chatRoomId":"096b8be1-2411-4cb1-94e0-ed96c51c23d8",
      "name":"Bar",
      "profilePicture":"...",
      "conversation":[  
         {  
            "name":"Bar",
            "message":"Hello!",
            "createdAt":"2018-09-30T06:50:49.000+0000"
         },
         {  
            "name":"Foo",
            "message":"Hi",
            "createdAt":"2018-09-30T11:49:05.000+0000"
         }
      ]
   }
]

TypeScript模型:

export interface Conversation {
  chatRoomId: string;
  name: string;
  profilePicture: string;
  conversation: ChatMessage[]
}

export interface ChatMessage {
  name: string;
  message: string;
  createdAt: string;
}

问题:

如果我在控制台中输出了变量,则对话(conversation: ChatMessage[])是一个空数组元素。

如果我使用this.http.get<any>('...')发出请求,则对话的获取将按预期方式存储。

1 个答案:

答案 0 :(得分:1)

您可以通过多种方式来完成您要尝试做的事情,但是根据我的经验,使用该库是最简单的:https://github.com/typestack/class-transformer

这是在您遇到的情况下如何工作的方法。首先,我将您的接口更改为Typescript类。

import { Type } from 'class-transformer';

export class Conversation {
    chatRoomId: string;
    name: string;
    profilePicture: string;

    @Type(() => ChatMessage)
    conversation: ChatMessage[]

    constructor(args: Conversation) {
      Object.assign(this, args);
    }
}

export class ChatMessage {
    name: string;
    message: string;
    createdAt: string;

    constructor(args: ChatMessage) {
      Object.assign(this, args);
    }
}

与这些接口的使用时间相比,有些变化:

  1. @Type装饰器的使用来自class-transformer模块。这使您可以转换嵌套对象。以下是文档:https://github.com/typestack/class-transformer#working-with-nested-objects
  2. 我们添加了constructor,可让您创建这些类的实例,并将属性传递给它们各自的类型。看看这篇帖子Converting httpClient answer to model objects [Angular 6],因为它可以使您更加了解这里发生的事情。

然后在您的服务中,这就是代码的更改方式:

import { plainToClass } from 'class-transformer';    

conversations: Conversation[];

// ChatService
getConversations() {
    return this.http.get<Conversation[]>('/chat/conversations');
}

this.chatService.getConversations().subscribe(
    (response: Conversation[]) => {
        this.conversations = plainToClass(Conversation, response) as Conversation[]
    }
);

plainToClass将获取原始JSON响应并将其转换为您的会话类的实例。如果您用console.logout退出this.conversations,则会看到它返回一个对话数组,每个对话数组都具有一个名为ChatMessage类型的名为conversations的数组属性。