我有一项使用@angular/http
从API加载数据的服务。
我想使用此数据为我的Components
创建检索数据的投影。
因此我写了以下代码:
getById(id: string) {
return this.http
.get(`https://my-api.io/${id}`)
.map(response => response.json())
.map(contracts =>
contracts.map(contract => # <- Nested map
new Contract(
contract['id'],
contract['description']
)
)
);
}
在第6行行中,我有一个嵌套的map
- 语句,降低了我的代码的可读性。
问题
我可以做得更好吗?在RxJS中是否有一个操作符,我可以使用它而不是创建这种嵌套?
提前致谢!
答案 0 :(得分:3)
我建议使用flatMap/selectMany将嵌套数组展平为每个单个数组元素的新流。在下一步中,您可以使用RxJS.map()
进行实际映射。最后将带有RxJS.toArray()
的所有映射数组元素收集到一个提供单个数组事件的新observable中:
const stream = $http('http://jsonplaceholder.typicode.com/posts')
.map(res => res.data)
.flatMap(posts => posts)
.map(post => Object.assign({}, post, { status: false }))
.toArray();
请在此处查看示例:http://jsbin.com/vigizihiwu/1/edit?js,console
但我也会考虑:真的有必要这样做吗?如果您只有一个订户,请将收到的数组映射到那里:
const stream = $http('http://jsonplaceholder.typicode.com/posts')
.map(res => res.data);
stream.subscribe(res => {
const posts = res.map(post => Object.assign({}, post, { status: false }));
console.log(posts);
});
答案 1 :(得分:2)
感谢@Alexander T.。在我看来,他提出了一种绕过嵌套map
的好方法 - 声明:http://jsbin.com/hududiq/1/edit?js,console
现在我的代码如下所示:
getByAccountId(id: string) {
return this.http
.get(`http://my-api.io/${id}`)
.map(contractsData => contractsData.json())
.concatAll()
.map(contract => Observable.of(new Contract(
contract['id'],
contract['description'])))
.combineAll();
}
答案 2 :(得分:2)
这似乎是一件非常简单的事情。
如果您想不惜一切代价避免嵌套map()
(即使这是两种完全不同的方法),您只能在结果数组中使用一个map()
然后forEach()
:
new Observable.of(testData)
.map(contractsData => {
var objects = [];
JSON.parse(contractsData).forEach(o => objects.push(new Contract(o['id'], o['description'])));
return objects;
})
.subscribe(val => console.log(val));
这将返回与您的代码相同的结果。
查看实时演示:http://plnkr.co/edit/NQgRVSCQGgPvTkPPGz7O(我还包含了您的代码以证明结果相同)。
我个人使用两个map()
,因为它更简单:
new Observable.of(testData)
.map(contractsData => JSON.parse(contractsData).map(o => new Contract(o['id'], o['description'])))
.subscribe(val => console.log(val));
顺便说一下,所有以*all
结尾的运算符都使用更高阶的Observables(也就是Observables发出其他Observables),我很惊讶你的代码可以工作,因为你将普通数组传递给.concatAll()
而不是一个可观察者。由于its inner subscriber,它原来是.concatAll()
的无证功能。 According to the documentation这不应该工作。