Рекурсивный с использованием expand () и concatMap () в Angular 7 - PullRequest
2 голосов
/ 31 мая 2019

У меня следующий список 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: ...
}

Я хочу просмотреть все URL-адреса после получения данных каждого вызова API, проверить, равна ли следующая переменная нулю.Если оно не равно нулю, оно продолжит работу.пока он проходит, данные каждого вызова 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

1 Ответ

1 голос
/ 31 мая 2019

Я исправил ваш код, как показано ниже ( исправлено: 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]

Другим моментом было ваше условие возврата пустого () было наоборот

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...