合并嵌套的observable的结果

时间:2018-01-10 11:09:28

标签: angular nested rxjs observable subscribe

我正在网上工作,我想检查商品是否已经在购物车中。我有两个需要完成这项工作的观察者:

1:从数据库中获取所有项目

this.itemsService
  .getAll()
  .subscribe(
    items => {
      console.log(items); // [{...},{...},{...},...]
    }
  );

2:如果一个项目在购物车中是三次,这个函数会给我一个带有三倍项目的数组的观察值。

public getItemFromCart(itemToGet) {
  return this.cart$.map(cartItems => {
    return cartItems.filter(
      (item: ICartItem) => itemToGet.id === item.idItem
    );
  });
}

我现在要做的是获取所有项目,使用 getItemFromCart 检查每个项目是否存在于购物车中,如果是,我需要设置属性 item.inCart = true 。否则它应该是假的......

我只想使用一个订阅而不想嵌套订阅...

this.itemsService
  .getAll()
  // do something here to check if the item in the array is present in the cart
  .subscribe(
    items => {
      console.log(items); // [{...},{...},{...},...]
    }
  );

提前致谢!

1 个答案:

答案 0 :(得分:1)

由于您同时拥有items$cart$,因此您可以使用combineLatestzip运算符,请按以下方式执行:

import { of } from 'rxjs/observable/of';
import { zip } from 'rxjs/observable/zip';   
import { combineLatest } from 'rxjs/observable/combineLatest';

// replace with your item service stream
const items$ = of([
  { id: 1, name: 'a' },
  { id: 2, name: 'b' },
  { id: 3, name: 'c' },
  { id: 4, name: 'd' },
  { id: 5, name: 'e' }
]);

// replace with your cart stream
const cart$ = of([
  { id: 1, name: 'a' },
  { id: 2, name: 'b' },
  { id: 3, name: 'c' }
]);

let result = [];
// use zip or combineLatest
combineLatest(items$, cart$)
  .subscribe(([items, cartItem]) => {
    result = items.map(item => ({
      ...item,
      inCart: !!cartItem.find(x => x.id === item.id)
    }));

    // 1, 2, 3 incart = true, 4, 5 incart = false
    console.log(result);
  });