![](/img/trans.png)
[英]Angular & RxJs : How to map json to Object Array
[英]Angular using RxJS - How to map data when JSON object has multiple properties
我的代碼最初有效,直到我需要更改 JSON 對象的結構。 這是我的原始 JSON 對象結構,它只是我的 API 返回的產品的簡單列表。 為簡潔起見,我縮寫為:
[{"PicFile":"11382","ShortDesc":"At Home Slot Machine","ActualPrice":12.99, .... }]
在我的產品服務中,我調用我的 API 並返回一個轉換為我的產品模型的列表:
getProductsByCategory(categoryCode: string): Observable<Product[]> {
let url = this.baseAPIUrl + .....
return this.httpClient.get(url)
.pipe(
map((data: any[]) => data.map((item) => this.adapter.convert(item)))
);
}
這是我的適配器代碼。 我創建了一個可以接收任何類型對象的通用適配器,這是它的實現:
import { Injectable } from "@angular/core";
import { Adapter } from "./adapter";
export class Product {
constructor(
public PicFile: string,
public ShortDesc: string,
public ActualPrice: number,
.... other properties here
) { }
}
@Injectable({
providedIn: "root",
})
export class ProductAdapter implements Adapter<Product> {
convert(item: any): Product {
return new Product(item.PicFile, item.ShortDesc, item.ActualPrice, .... );
}
}
在我的產品組件中,我訂閱了從服務返回的 observable:
loadAllProductsByCategory(categoryCode: string) {
this.loadingSubject.next(true);
this.productService.getProductsByCategory(categoryCode).pipe(
catchError(() => of([])),
finalize(() => this.loadingSubject.next(false))
)
.subscribe(products => this.productsSubject.next(products));
}
這與我的簡單 JSON 結構完美搭配。 我需要為分頁目的添加一個計數屬性,並且將來很可能會添加其他屬性。 新的 JSON 對象具有保存產品列表的“Data”屬性和名為“Count”的屬性。
{"Data":[{"PicFile":"11382","ShortDesc":"At Home Slot Machine","ActualPrice":12.99, ...}], "Count":41}
所以,我的問題是如何更改我的服務代碼以查找“數據”屬性並進行轉換?:
return this.httpClient.get(url)
.pipe(
map((data: any[]) => data.map((item) => this.adapter.convert(item))) <-- how to look for "Data" property and convert only that list, not the whole object?
);
我嘗試了幾件事,包括在此處訂閱,但隨后將其轉換為訂閱,我需要返回可觀察對象。 我相信它可以完成,但我對 Angular 和 RxJS 還很陌生。 我似乎無法正確找出映射語法。
提前感謝您提供的任何幫助,吉姆
如果返回的數據結構發生變化,則需要更新服務中的map
。
return this.httpClient.get(url).pipe(
map( (data: any) => data.Data.map((item) => this.adapter.convert(item)) )
);
您可能應該更改傳遞到地圖中的屬性名稱以避免混淆。 IE
(resp: any) => resp.Data.map((item) => this.adapter.convert(item))
從服務返回的數據結構已經從 Array 變為 Object。 因此,您必須更改映射過程
此更新后的代碼只會從您的響應中返回Data
數組。
如果還需要返回計數,則需要更新服務方法getProductsByCategory
以返回包含計數和數據的對象。
您可以嘗試以下方法:
return this.httpClient.get(url).pipe(
map((response: any) => {
response.data=response.data.map((item) => this.adapter.convert(item));
return response;
})
);
從服務獲取 JSON 時的常見映射模式是使用響應中的數據創建或豐富對象
return this.httpClient.get(url).pipe(
map(response => ({
ProcessingTimeStamp: Date.now(),
fullName: `${response.productName} (${response.productShortHand})`,
count: response.count,
data: response.Data.map(item => this.adapter.convert(item)),
foo: response.bar,
message: `I can sell you ${count}, of ${response.productShortHand} for cheap! Buy from me!`
}))
);
此模式將響應轉換為一個對象,您可以稍后隨意使用。 這里一個響應變成了一個對象,形式如下:
{
ProcessingTimeStamp: number,
fullName: string,
count: number,
data: item[],
foo: any,
message: string
}
你真的不受你能做什么的限制。 如果它適用於 TS/JS,你可以做到。 您可以推送函數或嵌套的 observables 等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.