Javascript 双组合测试不';不发射更新

Javascript 双组合测试不';不发射更新,javascript,firebase,google-cloud-firestore,rxjs,angularfire2,Javascript,Firebase,Google Cloud Firestore,Rxjs,Angularfire2,在我的项目中,有些活动是人们创建、加入、添加书签或组织的。我已经读过很多这样的问题了。但大多数代码都不那么复杂,或者人们忘记订阅了 我想获取特定时间段内的所有活动,然后添加创建者信息(姓名、图像等),如果检索这些活动的用户已加入/加入/组织了此活动,则添加布尔值。我以前使用的代码将提供实时更新(例如,我通过将我的用户ID添加到参与者数组来加入活动,activity.joined将更新为true) 以前的代码: public getActivities(user: UserProfileModel

在我的项目中,有些活动是人们创建、加入、添加书签或组织的。我已经读过很多这样的问题了。但大多数代码都不那么复杂,或者人们忘记订阅了

我想获取特定时间段内的所有活动,然后添加创建者信息(姓名、图像等),如果检索这些活动的用户已加入/加入/组织了此活动,则添加布尔值。我以前使用的代码将提供实时更新(例如,我通过将我的用户ID添加到参与者数组来加入活动,activity.joined将更新为true)

以前的代码:

public getActivities(user: UserProfileModel): Observable<Array<ActivityModel>> {
    const now: number = moment().startOf('day').unix();
    const later: number = moment().startOf('day').add(30, 'day').unix();
    return this.afs.collection<ActivityModel>(`cities/${user.city.id}/activities`, ref => ref
        .where('datetime', '>=', now)
        .where('datetime', '<=', later))
        .valueChanges({ idField: 'id' })
        .pipe(
            map(activities => activities.map(activity => {
                const bookmarked = activity.bookmarkers ? activity.bookmarkers.includes(user.uid) : false;
                const joined = activity.participants ? activity.participants.includes(user.uid) : false;
                const organized = activity.organizers ? activity.organizers.includes(user.uid) : false;
                return { bookmarked, joined, organized, ...activity } as ActivityModel;
        }))
    );
}
公共getActivities(用户:UserProfileModel):可观察{ const now:number=moment().startOf('day').unix(); const later:number=moment().startOf('day').add(30,'day').unix(); 返回此.afs.collection(`cities/${user.city.id}/activities`,ref=>ref .where('datetime','>=',now) .where('datetime','ref .where('datetime','>=',now)
。如果('datetime','看起来像是
activityCreator
中的一个未发出值,则CombineTest要求所有可观察对象至少发出一次

我建议您调试
activityCreator
的行为。 如果它不发射,那么您有两个选项:
startWith
为初始发射设置一个值,或者
defaultIfEmpty
,如果流将在没有任何发射的情况下关闭,它将发射

activityCreator=this.getCreator(activity.creator).pipe(
//startWith(null),//例如,如果要触发CombineTest。
//defaultIfEmpty(null),//如果是空流。
);

另一件事是
concatMap
它需要一个可观察的对象来完成,只有当它切换到下一个对象时,parhaps
mergeMap
switchMap
更适合这里

尝试下面的代码并将其输出添加到注释中。谢谢

const activityCreator:Observable=this.getCreator(activity.creator).pipe(
水龙头(
()=>console.log('getCreator:emit'),
()=>console.log('getCreator:error'),
()=>console.log('getCreator:completed'),
),
);

this.getCreator返回的observable是否完成?我认为它完成了。请参阅下面我对satanTime的回答。感谢您的回答。我已将行更改为:const activityCreator:obbservable=this.getCreator(activity.creator).pipe(startWith(null),//例如,如果要触发CombineTest.defaultIfEmpty(null),//如果流为空,则点击((creator)=>console.log(“get creator”,creator)))在控制台中,我首先得到null,然后是creatorObject。这看起来很好,对吗?是的。
startWith
总是作为第一个瞬间值发出。这就是为什么我还建议
defaultIfEmpty
-它在开始时不发出,但在流关闭时发出,没有任何发出。这取决于什么更符合您的要求。我想k我的问题有点不清楚。我已经添加了我的旧代码。该代码确实会在活动数组中发出更新。新代码不会。你认为在我的新代码中有什么会打破这一点?我可以在保留可观察创建者(用户)的同时修复它吗信息?知道了,我很快会检查并让你知道。你能检查一下答案的第二部分吗?
concatMap
是故意添加的,你能解释一下吗?
public getActivities(user: UserProfileModel): Observable<Array<CombinedActivityCreatorModel>> {
    const now: number = moment().startOf('day').unix();
    const later: number = moment().startOf('day').add(30, 'day').unix();
    return this.afs.collection<ActivityModel>(`cities/${user.city.id}/activities`, ref => ref
        .where('datetime', '>=', now)
        .where('datetime', '<=', later))
        .valueChanges({ idField: 'id' })
        .pipe(
            concatMap(activities => {
                const completeActivityData = activities.map(activity => {
                    const activityCreator: Observable<UserProfileModel> = this.getCreator(activity.creator);
                    const bookmarked = activity.bookmarkers ? activity.bookmarkers.includes(user.uid) : false;
                    const joined = activity.participants ? activity.participants.includes(user.uid) : false;
                    const organized = activity.organizers ? activity.organizers.includes(user.uid) : false;
                    return combineLatest([
                        of({ bookmarked, joined, organized, ...activity }),
                        activityCreator
                    ]).pipe(
                        map(([activityData, creatorObject]: [ActivityModel, UserProfileModel]) => {
                            return {
                                 ...activityData,
                                 creatorObject: creatorObject
                            } as CombinedActivityCreatorModel;
                        })
                    );
                });
            return combineLatest(completeActivityData);
        })
    );
}