我正在使用Angular和Firebase进行一个小项目。日期更改后,我需要获取在该日期或该日期之前创建的“问题”列表,以及当天该问题的单个“答案”。
当前日期是一个BehaviorSubject,因此当它发生更改时,我会使用switchmap获取该日期的问题和答案列表。
但是在使用forkJoin和map将两个数组合并/合并为一个数组之后,似乎没有任何显示。但是,如果我在forkJoin之前简单地返回QuestionsCollection,我会得到问题列表,但这无济于事,因为在那个日期我仍然没有该问题的答案。
因此,在产生forkJoin之前仅返回const q。 如下所示的问题列表(该answer属性是默认值,因为如果数据库中没有我,我会为该用户实例化一个新问题,一旦用户保存得分,便会添加该问题),但使用forkJoin,甚至没有返回[]
[
{
"id": "e0gdRmeNu2bheekeyT6m",
"uid": "uPhcLZkaRYRXpsSZC0zbRqUOWOq2",
"question": "Combine Q with A",
"goal": 10,
"answer": {
"id": null,
"score": null,
"qid": null,
},
...
]
在firebase中,“答案和问题”是单独的集合,因为用户每天只会收到1个答案,因此当我要求日期问题时,我不想获得所有以前的答案。
主要方法
getQuestions() {
//Observable<Question[]>
this.questions = this.dateService.dateStore
.pipe(
switchMap(date => {
const startDate = moment(date).startOf('day').utc().toDate();
const endDate = moment(date).endOf('day').utc().toDate();
//Observable<Question[]>
const q = this.getQuestionsUntilDate(endDate);
//Observable<Answer[]>
const a = this.getAnswersForDateRange(startDate, endDate);
//forkjoin and map results together?
//doesn't seem to work
return forkJoin([q, a])
.pipe(
map(val => {
let questions = val[0];
let answers = val[1];
questions.forEach(question => {
//a answer is not guaranteed to exist so only
//add it to the question if we found one.
const answer = answers.find(answer => answer.qid === question.id);
if (answer) {
question.answer = answer;
}
});
return questions;
}));
}))
}
问答集呼叫
private getQuestionsUntilDate(date: Date) {
return this.qCollection(ref => ref
.where('timestamp', '<=', date)
.where('uid', '==', this.auth.userId)
.orderBy('timestamp'))
.snapshotChanges()
.pipe(
map(res => {
return res.map(q => {
return new Question({
id: q.payload.doc.id,
...q.payload.doc.data()
})
})
})
);
}
private getAnswersForDateRange(sDate: Date, eDate: Date) {
return this.aCollection(ref => ref
.where('timestamp', '<=', eDate)
.where('timestamp', '>=', sDate)
.where('uid', '==', this.auth.userId))
.snapshotChanges()
.pipe(
map(res => {
return res.map(a => {
return new Answer({
id: a.payload.doc.id,
...a.payload.doc.data(),
})
})
})
);
}
答案 0 :(得分:1)
forkJoin
将在所有这些可观察物完成时发出给定可观察物的最后一个值。
似乎snapshotChanges()
会返回一个Observable,但不会发出第一个值。
zip
可让您按照发射顺序组合可观察值:第一个值与第一个值,第二个值与第二个值,等等。
如果您需要对任何流的更新做出反应,请尝试combineLatest
。
注意 ::您需要从zip
导入rxjs
,而不是rxjs/operators