Rx js mergeMap: Concat 2 связанных запросов API - PullRequest
1 голос
/ 04 февраля 2020

У меня есть два запроса API, второй зависит от первого. Первый запрос получает массив из 3 объектов. После этого мне нужно сделать запрос API для каждого объекта, чтобы получить изображение, которое мне нужно. Мне нужен UUID объектов. Я думал, что это может быть легко с MergeMap. Но у меня есть 2 проблемы, и я не могу найти решение: внутри карты слияния, я думал, что сервис будет одним из сервисов массива, но это целый массив. Также мне нужно подписаться на getImage () и сохранить значение внутри service.image.

getNewestNursingServices() {
  return this.http.get('api/nursing-service/newest').pipe(
   mergeMap(service => this.getImage('PREVIEW', service.uuid))
  );
}
getImage(type: string, nursingService: string): Observable<Image> {
  return this.http.get<Image>('api/nursing-images/' + type + '/' + nursingService);
}

Ответы [ 2 ]

2 голосов
/ 04 февраля 2020

Вы можете использовать forkJoin или concat:

getNewestNursingServices() {
  return this.http.get('api/nursing-service/newest').pipe(
   mergeMap((service: any[]) => {
     return concat(...service.map(s => {
       return this.getImage('PREVIEW', s.uuid)
     }) 
   }) 
  );
}
0 голосов
/ 04 февраля 2020

Надеюсь, я правильно понял вопрос.

Итак, вашей первой проблемой было то, что первый вызов API возвращает массив. Эту проблему можно решить с помощью mergeMap - сглаженного массива, так что наблюдаемая нисходящая линия будет испускать 3 сервиса последовательно.

getNewestNursingServices() {
  return this.http.get('api/nursing-service/newest')
    .pipe(
      mergeMap((services: []) => {
        // `of` will return an observable which emits the items of the array after each other
        return of(services);
      }),
      mergeMap(service => this.getImage('PREVIEW', service.uuid)),
      tap((image: Image) => {
        // here you can do sideeffects with the images, eg. pushing them into an array somewhere...
      }),
      reduce(
        (allImages: Image[], currentImage: Image) => {
          // ... or you can collect them into an array, so the downstream will be `Observable<Image[]>`
          allImages.push(currentImage);
          return allImages;
        },
        [],
      ),
    );
}

Что касается того, что вы должны подписаться, это не так, вы можете использовать результирующая наблюдаемая, например, в трубе async, если вы не хотите использовать шаблон побочного эффекта + подписки.

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