Luk*_*uke 2 observable rxjs angular rxjs6 angular7
使用RxJS v6很难从子集合中检索循环中每个项目的数据。无法迭代从HTTP调用检索的throw数组。合并映射仅对需要在所有数组项目上执行的单个项目执行此操作。
我已经坚持了三天。我已经尝试了一切。问题在于,新的管道语法在为您提供组织代码的巧妙方法的同时,没有简单的方法来循环引发数据收集。无法使用地图javascript函数,因为它在可观察范围之外并且返回的项目不确定。在互联网上,我只能找到一个很好的单个mergeMap的基本示例。但是,我需要使用带有http调用的数组中的每个项目,并将响应附加到同一对象。
我从第三方无法控制的两个端点开始。我嘲笑了一些示例API来说明。
端点1-返回所有项目ID: http:// localhost:3000 / contact
{
"name": "test",
"contact": [
{
"_id": "5c9dda9aca9c171d6ba4b87e"
},
{
"_id": "5c9ddb82ca9c171d6ba4b87f"
},
{
"_id": "5c9ddb8aca9c171d6ba4b880"
}
]
}
Run Code Online (Sandbox Code Playgroud)
端点2-返回单个项目信息: http:// localhost:3000 / contact / 5c9dda9aca9c171d6ba4b87e
[
{
"_id": "5c9dda9aca9c171d6ba4b87e",
"firstName": "Luke",
"lastName": "Test",
"email": "vgadgf@adsgasdg.com",
"created_date": "2019-03-29T08:43:06.344Z"
}
]
Run Code Online (Sandbox Code Playgroud)
期望的结果-通过使用RxJs v6 +返回带有嵌套数据的Observable:
{
"name": "test",
"contact": [
{
"_id": "5c9dda9aca9c171d6ba4b87e".
"relationship": {
"_id": "5c9dda9aca9c171d6ba4b87e",
"firstName": "Luke",
"lastName": "Test",
"email": "vgadgf@adsgasdg.com",
"created_date": "2019-03-29T08:43:06.344Z"
}
},
{
"_id": "5c9ddb82ca9c171d6ba4b87f",
"relationship": {
"_id": "5c9ddb82ca9c171d6ba4b87f",
"firstName": "Name2",
"lastName": "Test2",
"email": "vgadgf@adsgasdg2.com",
"created_date": "2019-03-29T08:43:06.344Z"
}
},
{
"_id": "5c9ddb8aca9c171d6ba4b880",
"relationship": {
"_id": "5c9ddb8aca9c171d6ba4b880",
"firstName": "Name3",
"lastName": "Test3",
"email": "vgadgf@adsgasdg3.com",
"created_date": "2019-03-29T08:43:06.344Z"
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
尝试使用Javascript循环时,我只是遇到错误,而使用不同的运算符也不能给我太多,因为RxJs中的循环存在问题。这是我产生的代码。请提供任何有用的建议或文档。
testService.service.ts
import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';
import {concatMap, map, mergeMap} from 'rxjs/operators';
@Injectable()
export class TestServiceService {
constructor(
private http: HttpClient
) { }
public getCombinedData(): Observable<any> {
return this.getMultipleRelationData()
.pipe(
map((result: any) => {
result = result.contact;
return result;
}),
mergeMap((fullResults: any) => {
return fullResults[0].relationship = this.getSingleData(fullResults[0]._id);
})
);
}
public getSingleData(id): Observable<any> {
return this.http.get('http://localhost:3000/contact/' + id);
}
public getMultipleRelationData(): Observable<any> {
return this.http.get('http://localhost:3000/contact');
}
}
Run Code Online (Sandbox Code Playgroud)
我当前的最终数据看起来只是一个项目。如果我只想打一个电话,那就太好了...但是,它与上述所需的输出相差甚远。
[
{
"_id": "5c9dda9aca9c171d6ba4b87e",
"firstName": "Luke",
"lastName": "Test",
"email": "vgadgf@adsgasdg.com",
"__v": 0,
"created_date": "2019-03-29T08:43:06.344Z"
}
]
Run Code Online (Sandbox Code Playgroud)
使用nested mergeMap和map。坚持使用Observable的一种关键方法是将Contacts数组扩展为Observable using from函数。然后使用toArray运算符收集数据。提供记录的示例:
public getCombinedData(): Observable<any> {
return this.getMultipleRelationData()
.pipe(
mergeMap((result: any) =>
// `from` emits each contact separately
from(result.contact).pipe(
// load each contact
mergeMap(
contact => this.getSignleData(contact._id),
// in result selector, connect fetched detail data
(original, detail) => ({...original, relationship: detail})
),
// collect all contacts into an array
toArray(),
// add the newly fetched data to original result
map(contact => ({ ...result, contact})),
)
),
);
}
Run Code Online (Sandbox Code Playgroud)
尽管 kvetis 的答案在这里对您有用,这是我实现的,只是发布它,因为我发现解决它很有趣。
public getCombinedData(): Observable<any> {
return this.getMultipleRelationData()
.pipe(
mergeMap((result: any) => {
let allIds = result.contact.map(id => this.getSingleData(id._id));
return forkJoin(...allIds).pipe(
map((idDataArray) => {
result.contact.forEach((eachContact, index) => {
eachContact.relationship = idDataArray[index];
})
return result;
})
)
})
);
}
Run Code Online (Sandbox Code Playgroud)
这是您问题的示例解决方案,我制作了虚拟 Observables。 https://stackblitz.com/edit/angular-tonn5q?file=src%2Fapp%2Fapi-calls.service.ts
| 归档时间: |
|
| 查看次数: |
1622 次 |
| 最近记录: |