RxJs: как объединить две наблюдаемые в новую наблюдаемую с другим типом

Я новичок в RxJs и NgRx store, я хочу создать @Effect с комбинацией двух наблюдаемых (очень сложно объяснить):

Мои интерфейсы выглядят так:

export interface ProductDetails {
  product: Product;
  productBody: ProductBody;
}

export interface ProductBody{
  id: string;
  body: string;
}

Я пытаюсь создать новый объектproductDetails и установить его свойства. свойства: product, который payload имеет product и productBody, который получает его от productService(id) (возвращает observable<productBody>)

Этот эффект должен вернуть observable<productDetails>

   @Effect()
  getProductDetails$ = this.actions$
    .ofType(ProductActions.GET_STEP)
    .map(action => action.payload)
    .flatMap(s => {
      let body;
      this.productService.getStepBody(s.id).subscribe(x => body = x);
      return Observable.of({
        step: s,
        productBody: body
      });
    })
    .map(res => this.productActions.getProductDetailsSuccess(res));

это возвращает: Object {productBody: undefined, product: Object}

Я понимаю, почему возвращается undefined для productBody, но не знаю, как это исправить. Я пробовал использовать zip, switchMap и т. Д., Но безуспешно!


person shiva    schedule 15.03.2017    source источник


Ответы (1)


Вот что ты можешь сделать.

  • Вы хотите flatMap над исходной наблюдаемой, чтобы получить payload.id, чтобы передать ее getStepBody наблюдаемой.
  • Затем внутри flatMap вы хотите map на getStepBody наблюдаемом, чтобы вернуть новое значение, которое является составным объектом payload и ответом getStepBody.
  • Наконец subscribe, чтобы получить окончательный результат.

Выглядит это примерно так:

getProductDetails$ = this.actions$
    .ofType(ProductActions.GET_STEP)
    .map(action => action.payload)
    .flatMap(payload => this.productService.getStepBody(payload.id).map(body => ({step: payload, productBody: body})))
    .subscribe(res => this.productActions.getProductDetailsSuccess(res));  //res is an object of {step: payload, productBody: body}

Если вы не хотите возвращать весь объект в одну функцию в функции subscribe, вы можете деструктурировать значения, чтобы упростить их использование по отдельности. Для этого измените строку subscribe на:

.subscribe(({step, body}) => {//do something with each value});
person Tyler Jennings    schedule 15.03.2017