1
votes

Having some real issues with how to achieve the following. I have a service with a function that returns a list of events with a key. I then want to pass this key to another function, which returns a more detailed object, in other data such as number of messages and owner information. Then I subscribe in component.

Currently I am using a .map operator with a forEach and then a subscribe to get the other info. I think I need to use a switchMap (to remove the inner subscribe) but cannot for the life of me get this to work. Have also tried flatMat, MergeMap, forkJoin and Observable.from but just confusing myself. Relevant start of code is below

return this.afs.collection<Event>(`users/${this.currentFirebaseUserObj.uid}/eventsByUser`)
    .valueChanges()
    .map((allEvents) => {allEvents.forEach(event =>{ 

Now I want to return the result of the getCompleteEvent() function, which returns an Observable of type Event to replace the above event object, and I am thinking I need to subscribe to this, but how can I return the result of the second call and replace the first Event Object i.e.

this.getCompleteEvent(event.key).subscribe(completeEvent => {
        return completeEvent
    }

On the other hand I can add specific fields to the Event Object in the forEach via different functions, but wanted a getComplete function to return the entire object after subscribing i.e.

event.userOwnerObj = this.getUserObject(event.ownerId);
event.noOfMessage = this.getNoOfMessages(event.key);

Feels like a mess and not sure of the best way to structure this part.

1

1 Answers

0
votes

I am not sure I have everything clear, but this may help.

Let's assume that

this.afs.collection<Event>(`users/${this.currentFirebaseUserObj.uid}/eventsByUser`).valueChanges()

returns an Observable which emits a collection with all the events, at least in their initial configuration, i.e. with the key but not all of the details.

If this is the case, then consider this code

this.afs.collection<Event>(`users/${this.currentFirebaseUserObj.uid}/eventsByUser`).valueChanges()
.switchMap(allEvents => from(allEvents))

This returns a stream which emits for each event found in allEvents. Now, for every event, you can run this.getCompleteEvent(event.key) which returns an Observable of the complete event.

Now you an use the mergeMap operator (formerly known as flatMap) to flatten the stream of Observables and obtain a stream of complete events. This means

this.afs.collection<Event>(`users/${this.currentFirebaseUserObj.uid}/eventsByUser`).valueChanges()
.switchMap(allEvents => from(allEvents))
.mergeMap(event => this.getCompleteEvent(event.key))
.subscribe(completeEvent => console.log(completeEvent) // do stuff with completeEvent)