Я использую Ionic 3, Firebase и FirebaseAuth. Я пытаюсь использовать пользователя, прошедшего проверку подлинности, для получения списка объектов для этого пользователя. Ниже моя попытка, и я получаю сообщение об ошибке
getContacts Error: TypeError: вы указали "undefined", где ожидался поток. Вы можете предоставить Observable, Promise, Array или Iterable.
Мне здесь что-то не хватает, поскольку кажется, что он должен обновлять onNext
с каждой новой частью данных.
Моя попытка:
getContacts() {
this.contactList.length = 0;
this.data.getAuthenticatedUserContactList().subscribe(
(contact => {
this.contactList.push(contact);
}),
(error => console.error('getContacts Error: ${error}'))
);
}
getAuthenticatedUserContactList() {
return this.afAuth.getAuthUser()
.flatMap(user => this.database.list('contact-lists/${user.uid}').take(1))
.flatMap((contactList) => {
if (contactList && contactList.length > 0) {
contactList.forEach(element => {
console.log('ForEach: ${element.userId}'); // THIS LOGS THE IDS AS EXPECTED
return this.database.object('/profiles/${uid}', { preserveSnapshot: true }).take(1);
});
} else {
return Observable.throw(new Error("No bros here"));
}
});
}
Любая помощь будет принята с благодарностью.
Решение по рекомендации forkJoin:
getContacts() {
this.contactList.length = 0;
this.data.getAuthenticatedUserContactList().subscribe(
(contact => {
contact.map(userContact => {
this.contactList.push(<UserProfile>(userContact));
});
}),
(error => console.error('getContacts Error: ${error}'))
);
}
getAuthenticatedUserContactList() {
return this.afAuth.getAuthUser()
.mergeMap(user => this.database.list('contact-lists/${user.uid}').take(1))
.mergeMap((contactList) => {
return Observable.forkJoin(contactList.map(element => this.getProfileWithUid(element.userId).map(userProfile => userProfile.val())))
});
}
getProfileWithUid(uid: string) {
this.profileObject = this.database.object('/profiles/${uid}', { preserveSnapshot: true });
return this.profileObject.take(1);
}
Во втором операторе flatMap()
вы ничего не возвращаете, когда это условие истинно:
contactList && contactList.length > 0
Оператор return
находится внутри forEach
обратного вызова.
Я не знаю, что логика вашего приложения, но обратный вызов flatMap
всегда должен вернуть Observable (или что-то, перечисленное здесь: http://reactivex.io/rxjs/class/es6/MiscJSDoc.js~ObservableInputDoc.html)
flatMap