我正在尝试将API调用的响应映射到一个Product对象。我似乎找不到适当的方法。
响应采用以下结构:
{
"data": [
{
"id": 1,
"name": "keyboard",
"details": {
"parent": 1,
"price": 50,
"other": "info"
}
},
{
"id": 2,
"name": "mouse",
"details": {
"parent": 2,
"other": "info",
"price": 20
}
}
],
"total-records": 2,
"more": "something"
}
不能保证响应详细信息的顺序。 (请注意价格)。我正在尝试将上面的对象映射到一个仅包含以下属性的新对象:
{
"id": 1,
"name": "keyboard",
"price": 50
},
{
"id": 2,
"name": "mouse",
"price": 20
}
我正在使用angular和Observables来获取数据。现在,我获取了值并将其映射,并且可以只获取详细信息或第一级对象属性,例如data.id
或data.name
。但是,获取价格之类的细节会让我感到困惑。
我已经研究了很多关于mergemap,flatmap,甚至lodash和无数小时的尝试,但是我似乎找不到正确的方法。
我可以在地图的组合中使用过滤器来实现此目的吗? 任何信息都将受到高度赞赏。
到目前为止,这是我的代码:
ngOnInit() {
//Get by criteria
this.productService
.get(url, httpOptions)
.pipe(
map((items: Response<Product>) => {
this.details = items["details"].filter(
// Filter possible null values
details=> details!==null;
);
this.header = items
}),
tap(() => console.log(this.header))
)
.subscribe();
}
// Header is level 1 info like name and id
// Detail is level 2 info like price.
// I have to have a filter on the details because sometimes
答案 0 :(得分:0)
它在那里不依赖RxJS,而是依赖简单的旧Javascript。
要将对象映射到期望的对象,请尝试以下操作:
this.productService
.get(url, httpOptions)
.pipe(
map((items: Response<Product>) => items
.map(item => ({ id: item.id, name: item.name, price: item.details && item.details.price || '?' }))),
tap(mappedItems => console.log(mappedItems))
)
.subscribe(mappedItems => this.header = mappedItems);
我还可以随意移动代码以使其更清晰(例如,在订阅中而不是直接在地图中进行操作)。
此代码的作用是映射Observable,使其返回一组新数据。
返回的新数据集也是一个映射,但是是实际数据的映射,而不是Observable的映射。
有了映射的数据,您现在可以将其应用到您的标头中,该标头是在订阅中创建的。
答案 1 :(得分:0)
从RxJS运算符内部分配“全局”是一种奇怪的工作方式。这些var应该从订阅中添加。而且捕获数据的方式也很奇怪。
您永远不会从响应中捕获“数据”属性,而将“细节”视为数组,但在响应中它是简单的对象。
继您的API重新使用之后,具有至少3个属性的1个对象 数据产品列表, 总记录, 更多 ...,
您可以做什么:
this.productService
.get(url, httpOptions).pipe(
map((res) => res.data), // extract data attribut
map((data) => {
return data.map((aProd) => { //map the product and take only id, name, price
return {
id: aProd.id,
name: aProd.name,
price: aProd.details && aProd.details.price
};
});
})).subscribe((productList) => {
console.log(productList);
});