angular - 根据响应递归组合 HTTP 结果

标签 angular recursion rxjs angular-httpclient

有一个 API( https://panelapp.genomicsengland.co.uk/api/v1/panels/?page=1 ),我想将所有数据消耗到我的 Angular 应用程序中。问题是他们的 API 有分页功能,我想一次检索所有内容。

正如您在 API 上看到的,它们的响应实际上具有指向下一页的“下一页”属性。我希望能够继续向 API 发出请求,只要“next”属性不为 null,然后将所有响应合并为一个。

我尝试过使用递归,但是当它到达第二个循环时,我得到了未定义的值。我的猜测是,这是因为异步请求,因此我得到了未定义。

下面是我的代码

@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);
  }

查看工作 stackblitz

关于angular - 根据响应递归组合 HTTP 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56786261/

相关文章:

angular - 如何向具有 Angular 1.X 背景的人解释 RxJS Subject

angular - 如何使用 Angular 作为 Material 将动画设置为 Nebular Stepper

angular - 如何使用 typescript/angular 2 正确使用 PrismJS 及其类型

python - 使用 Python 将字符串标记为嵌套数组列表

angular - 如何在 RXJS Angular 中的 concatmap 之间传递数据

angular - 将函数转换为可观察的

javascript - 找不到模块 : Error: Can't resolve 'crypto'

Python - 归并排序递归算法

arrays - 快速从数组中获取值并使用递归函数将它们放入另一个数组

rxjs - 将回调 hell 转换为可观察链