I'm syncing my app to firestore, listening for changes. When the app starts, it immediately dispatches a couple of actions to my store, to add the documents. I also have a NgRx effect waiting for the add action to be triggered to execute some code, mainly fetching other 2 documents from the references on the document dispatched with the action. I return a forkJoin and the effect only completes the last returned observable, ignoring all past ones.
I have already tried many RxJs operators to debounce, merge, and so on but it has the same result.
The service responsible for syncing the documents
fStore.collection<ReservationDocument>('reservations', query =>
query.where('hotel', '==', hotel.ref)
)
.stateChanges()
.subscribe(actions => {
actions.forEach(action => {
switch (action.type) {
case 'added':
console.log(action.payload);
store.dispatch(AddReservation({ reservation: action.payload }));
break;
case 'modified':
store.dispatch(ModifiyReservation({ reservation: action.payload }));
break;
case 'removed':
store.dispatch(RemoveReservation({ reservation: action.payload }));
break;
}
});
});
And the effect
getClientAndHotel$ = createEffect(() =>
this.actions$.pipe(
ofType(ADD_RESERVATION),
switchMap(
(addReservation: {
reservation: DocumentChange<ReservationDocument>;
}) => {
console.log('hello');
return forkJoin([
(addReservation.reservation.doc.get(
'client'
) as DocumentReference).get(),
(addReservation.reservation.doc.get(
'hotel'
) as DocumentReference).get()
]).pipe(
map(
result => {
console.log(addReservation.reservation.doc.ref.path);
return {
type: UPDATE_RESERVATION,
client: ClientFromDocumentData(
result[0].data() as ClientDocument,
result[0].ref
),
hotel: HotelFromDocumentData(
result[1].data() as HotelDocument,
result[1].ref
),
reservation: addReservation.reservation
};
}
)
);
}
)
)
);
I expect for forkJoin made to complete and dispatch an action, however, no matter how many times the effect was triggered, only the last trigger will dispatch the action. I suspect it simply overwrites the subscription every time the effect gets triggered, without waiting for the previous one to complete but I have no idea how to solve this issue.
As the comment on this questions mentions, you should use mergeMap
instead of switchMap
.
switchMap
will cancel a pending request, while mergeMap
will handle all requests. If the order of requests matters, use concatMap
.
https://rxjs-dev.firebaseapp.com/api/operators/mergeMap