So i have chained functions that return Promise, and in arguments i need to use values of observables. look at the descriptions in the code to understand. I think i should use some of rxjs operators to write this code in reactive programming way? but i don't now how to do it exactly, which of them to use.
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) {}
}
I would advise to go with the from operator instead of a Promise and model the whole operation as a RxJs stream.
One Option would be:
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
),
}))
} )
)
}