展平对象属性中的嵌套Observable

时间:2017-11-15 22:47:09

标签: node.js rxjs rxjs5

我是RxJs的新手,并尝试在我的节点应用中使用它。以下代码期望返回对象数组,并且每个对象应在其属性之一中具有嵌套数组。

现在问题是它返回了期望的Objects数组,除了内部observable(应该是一个数组)在订阅中仍然没有被展平。

createPlanOffers = (groupPlans) => {
    const groupPlan1 = groupPlans.filter(PREDICATE_1);
    return groupPlans
        .filter(PREDICATE_2)
        .reduce((offers, plan2) => {
            const plans_1 = groupPlan1.filter(PREDICATE_1_1);
            const plan1Details = plans_1.flatMap(plan1 => ({
                id: plan1.ID
            }));
            const offer = {
                groupKey: plan2.KEY,
                plan1Details: plan1Details
            };
            offers.push(offer);
            return offers;
        }, []);
};

const classPlans = query()
    .groupBy(group => group.KEY)
    .flatMap(groupPlans => createPlanOffers(groupPlans))
    .subscribe(group => console.log(group),
        err => console.log(err),
        () => console.log('complete'));

预期结果:

[
 { groupKey: 1111,
   plan1Details: [{id: xyz}]
 },
 { groupKey: 2222,
   plan1Details: [{id: xyz}]
 },
 { groupKey: 2222,
   plan1Details: [{id: abc}]
 } 
]

实际结果:(

[
 { groupKey: 1111,
   plan1Details: 
     Observable {
     _isScalar: false,
     source: [Observable],
     operator: [MergeMapOperator] } },
   { groupKey: 2222,
     plan1Details: 
       Observable {
       _isScalar: false,
       source: [Observable],
       operator: [MergeMapOperator] } },
   { groupKey: 2222,
     plan1Details: 
       Observable {
       _isScalar: false,
       source: [Observable],
       operator: [MergeMapOperator] } } 
]

此查询将返回如下内容:

const query = () => Rx.Observable.from([
    { KEY: 1111,
        id: 'xyz',
        category: 'A', // predicates are using these categories for filters
    }
    { GRGR_CK: 2222,
        id: 'xyz',
        category: 'A',
    }
    { GRGR_CK: 2222,
        id: 'ABC',
        category: 'B',
    }
])

2 个答案:

答案 0 :(得分:0)

这是因为flatMap没有从我的理解中递归解析Observables。您可以做的是添加另一个flatMap并在返回之前解析内部:

query()
    .groupBy(group => group.KEY)
    .flatMap(groupPlans => createPlanOffers (groupPlans))
    .flatMap(obj => // could destruct the values you want instead
       obj.plan1Details.map(
         val => Object.assign({}, obj, { plan1Details: val})
       )
    )
    .subscribe(group => console.log(group),
        err => console.log(err),
        () => console.log('complete'));

我不喜欢看/读的方式所以我会考虑解决这个问题,但不确定如何不查看完整的代码。

答案 1 :(得分:0)

您的plan1Details将是Observable,因为您使用Observable将其作为.flatMap()返回。

由于您有两个要过滤的谓词,其中两个谓词都在分组后进行过滤,因此您可以使用Observable.forkJoin()将它们组合并动态转换它们:

createPlanOffers = (groupPlans) => {
    const groupPlan1 = groupPlans.filter(PREDICATE_1);
    const groupPlan2 = groupPlans.filter(PREDICATE_2);
    return Observable.forkJoin([groupPlan1,groupPlan2])
        .map(([predicate1,predicate2])=>{
            predicate2.reduce((offers,plan2)=>{
                const offer = {
                    groupKey: plan2.KEY,
                    plan1Details: predicate1.map(plan1=>({id:plan1.ID})) //this map is an JS array.map(), not observable.map()
                };
                offers.push(offer);
                return offers

            },[])
        });
};

请注意,.map()的{​​{1}}是JavaScript的原生predicate1.map(),而不是array.map()