有一个 API(https://panelapp.genomicsengland.co.uk/api/v1/panels/?page=1)我想将所有数据消耗到我的角度应用程序中。问题是他们的 API 有分页,我想一次检索所有内容。
正如您在 API 上看到的,它们的响应实际上有“下一页”属性,指向下一页。我希望能够继续从 API 发出请求,只要“下一个”属性不为空,然后将所有响应合并为一个。
我尝试过使用递归,但是当它到达第二个循环时,我得到了未定义的值。我的猜测是,这是因为异步请求,因此我得到了未定义。
下面是我的代码
@Injectable()
export class GenomicsEnglandService {
panels = [];
constructor(private http: HttpClient) {
}
getPanels(url): Observable<any>{
const headers = new HttpHeaders()
.append('Content-Type', 'application/json')
.append('Accept', '*/*');
return this.http.get(url, {headers: headers})
.map((data) => {
panels = panels.concat(data.results);
if(data.next){
this.getPanels(data.next);
}else{
return panels;
}
})
.catch((e) => {
Raven.captureMessage("GENOMICS ENGLAND ERROR: " + JSON.stringify(e));
return of([]);
});
}
}
然后从我刚刚调用的组件中
this.GenomicsEnglandService.getPanels('https://panelapp.genomicsengland.co.uk/api/v1/panels/?page=1').subscribe(data => {
console.log(data);
})
虽然这个问题已经得到解答,但我想提出另一种方法,使用expand
操作员 [https://rxjs-dev.firebaseapp.com/api/operators/expand]. expand
运算符是为了这样的递归目的而创建的:
getResult() {
const url = "https://panelapp.genomicsengland.co.uk/api/v1/panels/";
return this.getResponse(url)
.pipe(
expand((res: any) => this.getResponse(res.next)),
takeWhile((res: any) => res.next, true),
concatMap((res: any) => res.results),
reduce((acc, val) => {
acc.push(val);
return acc;
}, []),
tap(_ => {
console.log(_);
this.loading = false;
})
)
}
getResponse(url) {
return this.httpClient.get(url);
}
查看工作堆栈闪电战
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)