Let's say I have a following structure, that means that user have and array of objects containing references to groups. I need to get a single observable for an array of referenced groups. How do I do that? I've tried a lot of different ways but no one is correct.
Here's what I came up with so far:
export interface Group { students: DocumentReference[]; title: string; } @Injectable() export class GroupsService { constructor(private afs: AngularFirestore, private tutorsService: TutorsService) { } getCurrentTutorGroups(): Observable<Group[]> { return this.tutorsService.tutor.pipe( map(tutor => { return tutor.groupSubjects.map(groupSubject => groupSubject.group.get()); }), mergeMap(group => fromPromise(group)), map(group => group.data() as Group) ); } }
GroupSubjects { group: DocumentReference; subject: DocumentReference; } interface Tutor extends User { groupSubjects: GroupSubjects[]; } @Injectable() export class TutorsService { tutor: Observable<Tutor>; constructor(private afs: AngularFirestore, private authService: AuthService) { this.tutor = this.authService.user.map((user: User) => { return {...user} as Tutor; }); } }
export interface User { uid: string; email: string; name: string; role: string; } @Injectable() export class AuthService { user: Observable<User | null>; constructor(private afAuth: AngularFireAuth, private afs: AngularFirestore) { this.setUser(); } private setUser() { this.user = this.afAuth.authState .switchMap((user) => { if (user) { return this.afs.doc<User>(`users/${user.uid}`).snapshotChanges().map(action => { return {uid: action.payload.id, ...action.payload.data()}; }); } else { return Observable.of(null); } }); } }
I need function getCurrentTutorGroups to return observable of type Group[].
Here's my solution after all the struggle
import { Injectable } from '@angular/core'; import {AngularFirestore} from 'angularfire2/firestore'; import {Observable} from 'rxjs/rx'; import 'rxjs/add/operator/mergeMap'; import 'rxjs/add/operator/map'; import { firestore} from 'firebase'; import DocumentReference = firestore.DocumentReference; import {GroupSubjects, TutorsService} from './tutors.service'; import {fromPromise} from 'rxjs/observable/fromPromise'; export interface Group { students: DocumentReference[]; title: string; } @Injectable() export class GroupsService { constructor(private afs: AngularFirestore, private tutorsService: TutorsService) { } private getTutorGroupsObservableArray(groupSubjects: GroupSubjects[]): Observable<Group>[] { return groupSubjects.map(groupSubject => fromPromise<Group>(groupSubject.group.get().then(group => group.data() as Group))); } getCurrentTutorGroups(): Observable<Group[]> { return this.tutorsService.tutor.map(tutor => Observable.combineLatest(this.getTutorGroupsObservableArray(tutor.groupSubjects))).mergeMap(group => group); } }
Remember to add
import {Observable} from 'rxjs/rx';
instead of
import {Observable} from 'rxjs/Observable';
And one more thing that helped me finding the way to do that is that I added my private method for this code to be more obvious.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.