Así que tengo funciones encadenadas que devuelven Promise, y en los argumentos necesito usar valores de observables. mire las descripciones en el código para entender. Creo que debería usar algunos de los operadores rxjs para escribir este código en forma de programación reactiva. pero no sé cómo hacerlo exactamente, cuál de ellos usar.
interface User { email: string; conversations: string[] | FieldValue; userId: string; } @Injectable({ providedIn: 'root', }) export class ConversationsClientService { getUserByEmail(email: string): Observable<any> { // should return Observable<User[]> but this function return type is Observable<unknown[]> and i can't use this type, but thats not the main issue return this.firestore .collection('users', (ref) => ref.where('email', '==', email)) .valueChanges(); } startNewConversation( currentUserCredential: Observable<firebase.auth.UserCredential>, //that comes from ngrx selector email: string ): Promise<void> { //or return observable by wrapping promise with from() operator return this.firestore .doc<User>( 'users/' + 'there should be .user.uid field of value of observable currentUserCredential' ) .update({ conversations: arrayUnion( 'there should be [0].userId field of value of observable getUserByEmail(email)' ), }); } constructor(private firestore: AngularFirestore) {} }Aconsejaría ir con el operador from en lugar de Promise y modelar toda la operación como un flujo RxJs.
Una opción sería:
startNewConversation( currentUserCredential: Observable<firebase.auth.UserCredential>, //that comes from ngrx selector email: string ): Promise<void> { /* combineLatest will emit an array with the most recent emitted values of the combined observables */ return combineLatest([currentUserCredential, this.getUserByEmail(email)]).pipe( switchMap((currentUserAndUserByEmail) => { return from(this.firestore .doc<User>( 'users/' + currentUserAndUserByEmail[0].user.uid, ) .update({ conversations: arrayUnion( currentUserAndUserByEmail[1][0].userId ), })) } ) ) }