javascript - 在 Angular 7 中递归使用 expand() 和 concatMap()

标签 javascript angular typescript rxjs

我在下面有以下 API 列表:

1. https://www.something.com/?filter=something

Result: 
{ 
  id: 12
  previous: null
  next: https://www.something.com/?filter=something&page=2
  data: ...
}

2. https://www.something.com/?filter=something&page=2

Result: 
{ 
  id: 13
  previous: https://www.something.com/?filter=something
  next: https://www.something.com/?filter=something&page=3
  data: ...
}

3. https://www.something.com/?filter=something&page=3

Result: 
{ 
  id: 14
  previous: https://www.something.com/?filter=something&page=2
  next: null
  data: ...
}

我想在获取每个 API 调用的数据后遍历所有 url,检查下一个变量是否为 null。如果它不为空,它将继续继续。在进行过程中,每个 API 调用的数据将被合并并返回输出。

这是我一直在尝试的

 getByURL(url: string): any {
    return this.apiService.get(url).pipe(map(data => data));
  }

  getData(): Observable<any> {
    const url = 'https://www.something.com/?filter=something';
    return this.getByURL(url).pipe(
      expand(({ data }) => {
        if (!data.next) return this.getByURL(data.next);
        else return empty();
      }),
      concatMap(({ content }) => {
        return of(content.data);
      })
    );
  }

但是我得到了未定义的结果,我已经为此奋斗了好几天。谢谢

已更新

我将我的代码放在 stackblitz 中: 我有 3 个 api 调用:

http://5cf15627c936cb001450bd0a.mockapi.io/users
http://5cf15627c936cb001450bd0a.mockapi.io/users2
http://5cf15627c936cb001450bd0a.mockapi.io/users3

我想在每次请求后收集所有数据。请查看控制台以查看输出。我总是不确定。谢谢

https://stackblitz.com/edit/angular-rai6az?file=src%2Fapp%2Fapp.component.ts

最佳答案

我修复了你的代码如下 ( fixed stackblitz )

  ngOnInit() {
    this.getByPageNext()
      .subscribe(data => {
        console.log(data);
      });
  }

  get(url: string): Observable<any> {
    return this.httpClient
      .get(url)
      .pipe(catchError(this.formatErrors));
  }

  formatErrors(error: any) {
    console.error('error', error);
    return throwError(error.error);
  }

  getByURL(url: string): any {
    return this.get(url);
  }

  getByPageNext(): Observable<any> {
    const url = 'https://5cf15627c936cb001450bd0a.mockapi.io/users2';
    return this.getByURL(url)
      .pipe(
        expand((response: Array<any>) => {
          if (response && response.length && response[0].next) {
              return this.getByURL(response[0].next);
          }
          else {
            return empty()
          }
        }),
        map(obj => obj[0]), 
        reduce((acc, x: any) => acc.concat([x.data]), []),
      );
  }

因此它将所有数据连接为数组,并且递归调用 http 工作正常。

唯一的问题是调用“https://5cf15627c936cb001450bd0a.mockapi.io/users”时' 下一个 url 是 http 而不是 https 这将导致 HttpError -> ProgressEvent。

所以我从“https://5cf15627c936cb001450bd0a.mockapi.io/users2”开始' 并且休息工作正常。因此,在您更改后端以修复下一个链接后,请将其更改回您的原始请求。

另一点是你从 api 返回的结果是一个数组而不是一个对象,这就是为什么我访问 result[0]

另一点是你返回 empty() 的条件反之亦然

关于javascript - 在 Angular 7 中递归使用 expand() 和 concatMap(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56398014/

相关文章:

angularjs - 如何使用具有构造函数参数的 TypeScript 类定义 AngularJS 工厂

javascript - Bootstrap Modal 引用输入字段值(不起作用)

javascript - AmSerialChart ValueAxis 起始值和增量

angular - 自定义组件值未使用 Angular Reactive Form 进行更新

javascript - 为什么我的 Jasmine spy 没有被召唤?

javascript - Angular 路由解析 - deferred.reject 不起作用 - Angular 1 + TypeScript

javascript - Jquery - trim 内部 HTML?

javascript - 如何使用一个 html5 音频播放器播放多个音频文件

javascript - 当输入字段已预填充时,该字段无效

javascript - 访问和操作订阅的可观察数据