Как объединить две коллекции Firebase в новый массив объектов - PullRequest
2 голосов
/ 06 апреля 2019

Я работаю над небольшим проектом с Angular и Firebase. При изменении даты мне нужно получить список «Вопросов», которые были созданы, в эту дату или ранее, а также один «Ответ» на этот Вопрос за этот день.

Текущей датой является BehaviorSubject, поэтому при ее изменении я использую карту переключателей, чтобы получить список вопросов и ответов на эту дату.

Но кажется, что после использования forkJoin и map для объединения / объединения двух массивов в одну, на моей странице ничего не отображается. Но если я просто верну коллекцию вопросов перед тем, как форкнуть Join, я получу список вопросов, но это не поможет, потому что у меня все еще не будет ответа на этот вопрос в эту дату.

Таким образом, возвращая только const q, прежде чем forkJoin приведет к. список вопросов, подобных приведенному ниже (это свойство ответа является значением по умолчанию, потому что, если у меня нет одного I из базы данных, я создаю новый для пользователя, который будет добавлен после сохранения счета), но с использованием forkJoin, даже не возвращает []

[
 {
"id": "e0gdRmeNu2bheekeyT6m",
"uid": "uPhcLZkaRYRXpsSZC0zbRqUOWOq2",
"question": "Combine Q with A",
"goal": 10,
"answer": {
  "id": null,
  "score": null,
  "qid": null,
},
...
]

В Firebase Ответы и Вопросы - это отдельные коллекции, потому что у пользователя будет только один ответ в день. Я не хочу получать все предыдущие ответы, когда я спрашиваю Вопросы на Дату.

Основной метод

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(),
                    })
                })
            })
        );
}

1 Ответ

1 голос
/ 06 апреля 2019

forkJoin будет испускать последние значения из данных наблюдаемых, когда все эти наблюдаемые полные .

forkJoin marble diagram

И, похоже, snapshotChanges() возвращает вам наблюдаемый объект, который не завершится выдачей первых значений.

Поэтому попробуйте заменить forkJoin на zip, например.

zip позволит вам объединить значения из наблюдаемых в порядке эмиссии: 1-е значение с 1-м значением, 2-е с 2-м и т. Д.

Если вам нужно реагировать на обновления из любого из потоков - попробуйте combineLatest.

ПРИМЕЧАНИЕ : Вам необходимо импортировать zip из rxjs, а не rxjs/operators

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...