RxJS: в зависимости от предыдущих значений восстановить объект, а затем соединить и выдать эти предыдущие значения с восстановленным объектом - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть случай, в котором у меня есть набор идентификаторов, которые я восстанавливаю из route.params, например:

const ids$ = this.route.params.pipe(
  map(params => {
    const modelId = +params['modelId'];
    const deliverId = +params['deliverId'];
    const compositionId = +params['compositionId'];

    return { modelId, deliverId, compositionId };
  })
);

После этого мне нужно восстановить объект composition с сервера, поэтому я делаю это:

const getComposition$ = ids$.pipe(
  switchMap(ids =>
    this.compositionsService.getComposition(ids.compositionId)
  )
);

А теперь я хочу иметь агрегированный объект с двумя первыми идентификаторами и вместо последнего (compositionId) объект composition, я имею в видуэто:

entities: {
  modelId: number;
  deliverId: number;
  composition: Composition;
};

Итак, я делаю это:

const aggregated$ = forkJoin(ids$, getComposition$).pipe(
  map(arr => ({
    modelId: arr[0].modelId,
    deliverId: arr[0].deliverId,
    aggregated: arr[1]
  }))
);

И затем я подписываюсь на него:

const aggregated$.subscribe(aggregated => {
  console.log(aggregated);
});

Но он никогда ничего не печатает на консоли,Интересно, что если я проверяю, сделан ли вызов серверу, это действительно так, но последнее наблюдаемое (aggregated$) никогда ничего не излучает.

Что я делаю не так?Есть ли лучший способ добиться этого?

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Из документации по Observable:

forkJoin: дождитесь завершения Observables и затем объедините последние значения, которые они испустили.

Я думаю, что forkJoin в вашем случае делаетне излучает, так как ids$ не завершается.

То, что вы можете попробовать, это что-то вроде этого

const getComposition$ = ids$.pipe(
  switchMap(ids =>
    this.compositionsService.getComposition(ids.compositionId).pipe(
       map(composition => ({composition, modelId: ids.modelId, deliverId: ids.deliverId))
    )
  )
);
0 голосов
/ 26 сентября 2018

Как вы сказали, ids$ и getComposition$ на самом деле this.route.params, что происходит от Angular.Оператору forkJoin нужны все его исходные наблюдаемые, чтобы испустить хотя бы один элемент, и все они должны завершить .И это то, что не происходит, когда вы используете this.route.params, потому что это субъект, который никогда не завершается.

Таким образом, вы можете использовать, например, take(1) для завершения обоих источников ids$ и getComposition$:

forkJoin(ids$.pipe(take(1)), getComposition$.pipe(take(1))
  ...
...