My app has 3 download buttons Each button click will dispatch DownloadFileAction(payload=fileId) An Effect will keep listening for Download_File_Action type
@effect()
download_attachment$: Observable = this.actions$
.ofType(FileActions.ActionTypes.DOWNLOAD_ATTACHMENT)
.map(toPayload)
.switchMap( attachment => {
return this.service.downloadAttachment(attachment.link) //absolute link
.map( (data) => {
this.service.saveAttachment(data); //save file locally
return new FileActions.DownloadAttachmentSuccessAction(attachment);
})
.catch(error => {
//debugger;
console.log(error);
});
})
If more than 1 button are clicked at the same time, 2 DownloadFileAction actions will be dispatched
Howerver, download_attachment$ effect only listen for one which is downloaded first and then return DownloadAttachmentSuccessAction, thus the other downloading files will not be finished
Is there any solution or workaround ? Your idea is much appreciated
As @cartant mentioned in a comment, replace switchMap with mergeMap.
The difference being, switchMap will switch contexts everytime the parent observable fires and mergeMap will keep listening to the parent observable and merge or combine the results.
In essence the switchMap is unsubscribing from the parent observable's first stream when the parent observable emits a new value.

In the marble diagram, you can see when 3 is emitted and then 5 is emitted, the final output doesn't include 3 30s because when 5 was emitted, it switched contexts and the values are dropped.
MergeMap will merge all the values emitted from the parent observable.

In the marble diagram for mergeMap you can see all values get emitted for every value emitted from the parent observable. ie, all 30s get emitted, even though the last value comes in after 5 is emitted from the parent.
Hope that helps illustrate it a little better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With