所以我有一个NgRx选择器,该选择器返回带有一个Contacts数组的Observable。我想映射此流,并针对每个联系人数组,映射每个单独的联系人,并向Github发出Http请求以获取其个人资料图片,并将其附加到Contact对象。但是,我不确定如何在不以Observable数组Observable结尾的情况下执行此操作。
下面是我尝试过的方法,但这不起作用。
this.contacts$: Observable<Contact[]> = this.store.select(getContacts).pipe(
map(contacts => {
return contacts.map(contact => {
return this.contactService.getGithub$(contact._id).pipe(
map(githubInfo => {
return {
...contact,
imageUrl: githubInfo.avatar_url
};
})
);
});
})
);
以下是我收到的错误消息:
Type 'Observable<Observable<Contact>[]>' is not assignable to type 'Observable<Contact[]>'.
Type 'Observable<Contact>[]' is not assignable to type 'Contact[]'.
Type 'Observable<Contact>' is missing the following properties from type 'Contact': first_name, last_name, job_title, location, company ts(2322)
任何建议将不胜感激!
答案 0 :(得分:1)
使用switchMap
将contacts
数组映射到Observable,该数组同时执行您的http请求并将它们映射到扩展的Contact对象。
this.contacts$: Observable<Contact[]> = this.store.select(getContacts).pipe(
switchMap(contacts => forkJoin(
contacts.map(contact => this.contactService.getGithub$(contact._id).pipe(
map(gitHubInfo => ({ ...contact, imageUrl: githubInfo.avatar_url }))
))
))
);
答案 1 :(得分:0)
这里的问题是,您正在运行一个Array.map
,它为每个contact
返回一个Observable。如果您希望Observable返回完整的数组,则需要这样的内容:
this.contacts$: Observable<Contact[]> = this.store.select(getContacts).pipe(
// take the array and emit each value one by one
concatMap(contacts => from(contacts)),
// emit an array containing the contact and the corresponding githubInfo
concatMap(contact => forkJoin(of(contact), this.contactService.getGithub$(contact._id))),
// take the returned array and convert it to an Object
map(([contact, githubInfo]) => ({ ...contact, imageUrl: githubInfo.avatar_url})),
// concatenate everything into a final Array
toArray()
);
我必须承认我是在旅途中写的,因此无需测试,但我认为它应该可以工作!
如果保持原始顺序很重要,请保留concatMap
。如果不是,请使用mergeMap
来提高性能。
答案 2 :(得分:-1)
this.contacts$: Observable<Contact[]> = this.store.select(getContacts).pipe(
map(contacts => {
return contacts.map(contact => {
return this.contactService.getGithub$(contact._id).pipe(
map(githubInfo => {
return { ...contact, imageUrl: githubInfo.avatar_url };
})
);
});
}),
concatAll()
);
只需在管道流中添加concatAll
运算符即可。