根据响应递归组合HTTP结果 [英] Recursively combining HTTP results based on response
问题描述
有一个API( https://panelapp.genomicsengland. co.uk/api/v1/panels/?page=1 ),我想将所有数据消耗到我的角度应用程序中.问题在于他们的API具有分页功能,我想一次检索所有内容.
如您在API上所见,它们实际上在响应中具有指向下一页的"next"属性.我希望只要"next"属性不为null,就可以继续向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);
})
尽管已回答了该问题,但我想通过使用 查看正在运行的 stackblitz > There's an API(https://panelapp.genomicsengland.co.uk/api/v1/panels/?page=1) that I want to consume all the data to my angular apps. The problem is that their API have pagination, and I want to retrieve all of the content at once. As you can see on the API, they actually have "next" attribute on their response which point to the next page. I want to be able to keep requesting from the API as long as "next" attribute is not null then combine all their response into one. I have tried using recursive, but by the time it reach the 2nd loop I get undefined value. My guess is that its because async request, hence I get undefined. Below is my code Then from my component I just called
Although this question has been answered, I would like to propose another approach by using See working stackblitz 这篇关于根据响应递归组合HTTP结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!expand
运算符[@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
operator [https://rxjs-dev.firebaseapp.com/api/operators/expand]. expand
operator is made for such recursive purposes: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);
}