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 30
s 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 30
s 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