我需要从Angular向我的数据库执行一系列HTTP请求。第一步,我得到一个对象数组。一切正常。 在第二步中,我想用其他数据填充每个对象。因此,我需要等待第一个http.request完成。 我也不想在获取数据之前返回。
我的函数getData()应该返回一个Observable,因为接口/签名不应该更改(因为它在程序的其他部分中使用,并且observable对程序逻辑有意义)。
// Returns an array with objects, that have an id, that is needed for the second call
data[] : Object = new Array();
populatedData[] : Object = new Array();
getData(): Observable<Object[]>{
this.http.get<Object[]>("http://localhost:3000/data").subscribe(data => this.data = data);
// This needs the data from the first call
for(int i = 0; i < data.length; i++){
this.http.get<Object>("http://localhost:3000/data/"+data[i].id).subscribe(data => populatedData.push(data));
}
return of(populatedData);
}
答案 0 :(得分:2)
您可以使用switchMap
(完成初始GET之后,发出其他请求)和forkJoin
(发出多个请求并在所有请求完成时发出)。像这样:
getSingleEntry = ({ id }) => this.http.get<Object[]>("http://localhost:3000/data/" + id);
getData = () => this.http.get<Object[]>("http://localhost:3000/data")
.pipe(
tap(data => this.data = data),
switchMap(data => forkJoin(data.map(this.getSingleEntry)));
答案 1 :(得分:1)
Promise是一个选项,但另一个选项可以是
// Returns an array with objects, that have an id, that is needed for the second call
data[] : Object = new Array();
populatedData[] : Object = new Array();
getData(): Observable<Object[]>{
this.http.get<Object[]>("http://localhost:3000/data").subscribe((data)=>{
this.data = data;
for(int i = 0; i < data.length; i++){
this.http.get<Object>("http://localhost:3000/data/"+data[i].id).subscribe((response)=> {
populatedData.push(response)
});
}
});
return of(populatedData);
}
答案 2 :(得分:0)
我认为最好的方法是使用switchMap
RXJS运算符和zip
。在第二次通话中,您可以访问第一个通话中的数据。然后,您可以在完成所有调用后返回值数组。
有关switchMap
的更多信息,您可以阅读here。关于zip
here。
这里有一个示例,数据如何显示为https://rxviz.com/v/Mogdv96O
然后您的代码将被重构如下:
getData(): Observable<Object[]> {
this.http.get<Object[]>("http://localhost:3000/data")
.pipe(switchMap((data) =>
zip(...data.map(item => this.http.get<Object>("http://localhost:3000/data/" + item.id)))
)
);
}
答案 3 :(得分:-1)
您应该将需要第一次调用的代码放入第二次
data: Array<any> = [];
populatedData: Array<any> = [];
getData(): Observable<Object[]> {
this.http.get<Object[]>('http://localhost:3000/data').subscribe(data => {
this.data = data;
for (let i = 0; i < data.length; i++) {
this.http
.get<Object>('http://localhost:3000/data/' + data[i].id)
.subscribe(data => populatedData.push(data));
}
});
return of(populatedData);
}