Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
88
rated 0 times [  91] [ 3]  / answers: 1 / hits: 18093  / 6 Years ago, thu, december 6, 2018, 12:00:00

I am definitely sure I am confused here so please any help is appreciated.



Here is my scenario:



I pull from Firestore a document:



return this.afs.collection(events).doc(eventID).snapshotChanges().pipe(
map( document => {

})
);


All is fine up to here.



But inside the map I need a promise to resolve (or not)



For example:



return this.afs.collection(events).doc(eventID).snapshotChanges().pipe(
map( document => {
// This is a promise the below part
const data = await EventImporterJSON.getFromJSON(document.payload.data())
return data
})
);


I understand that the await cannot happen there. I am very confused how to solve this, perhaps I have not worked long enough with observables and rxjs.



In the end what I am trying to achieve is:



Get the document. Map and process it but inside the process, I need to handle a promise.



I don't want to return that promise to the caller though.



Does this make sense?



Or have I structured this completely wrong?


More From » rxjs

 Answers
17

This is a typical use-case for mergeMap or concatMap:


return this.afs.collection("events").doc(eventID).snapshotChanges().pipe(
mergeMap(document => {
// This is a promise the below part
return EventImporterJSON.getFromJSON(document.payload.data())
})
);

However, you can also use async - await because operators such as mergeMap handle Observables, Promises, arrays, etc. the same way, so you can just return a Promise in mergeMaps project function it will work fine.


Typically, you don't need to use multiple awaits in a single method because the more "Rx" way of doing things is chaining operators, but if you want, you can because the async method returns a Promise and RxJS will handle it like any other Promise.


const delayedPromise = () => new Promise(resolve => {
setTimeout(() => resolve(), 1000);
})

of('a').pipe(
mergeMap(async v => {
console.log(1);
await delayedPromise();
console.log(2);
await delayedPromise();
console.log(3);
await delayedPromise();
return v;
})
).subscribe(console.log);
// 1
// 2
// 3
// a


Live demo: https://stackblitz.com/edit/rxjs-3fujcs

[#52968] Monday, December 3, 2018, 6 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
margaritakristinak

Total Points: 502
Total Questions: 127
Total Answers: 98

Location: England
Member since Mon, May 17, 2021
3 Years ago
;