json - 元素陣列不會被介面填充
我在 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
有幾種方法可以做到你想做的事,但根據我的經驗,使用這個函式庫是最簡單的: 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);
}
}
從這些是介面時起,有一些事情改變了:
- 使用
@Type裝飾器來自 class-transformer 模組。這允許你轉換嵌套物件。這裡是文件說明: https://github.com/typestack/class-transformer#working-with-nested-objects - 我們已經新增了一個
constructor,它允許你創建這些類別的實例,並傳遞其各自類型的屬性給它們。看看這篇文章《將 httpClient 的回應轉換為模型對象 [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 回應轉換為你的 Conversation 類別的實例。如果你對 this.conversations 使用 console.log,你會看到它返回的是一個 Conversations 的陣列,每個 Conversations 都有一個名為 conversations 的陣列屬性,其類型為 ChatMessage。
