Reputation: 428
My applications requires a two stage approach to uploading file:
It's also important to:
I'm using Angular 9 and NGRX 9, and would like the above to happen as one Action when the user selects a file. From NGRX's documentation, I believe this would be a concatMap operation, but I've yet to have success. The closest I've come is the following:
saveAndUploadDocument$ = createEffect(() => {
return this.actions$.pipe(
ofType(DocumentActions.saveAndUploadDocument),
switchMap(action => this.documentService.saveDocument(action.file).pipe(
switchMap(response => this.documentService.uploadDocument(action.file, response.document, response.sasToken).pipe(
map(token => DocumentActions.saveDocumentSuccess({document: response.document})),
catchError(error => of(DocumentActions.saveDocumentFailure({ error }))))
),
)
),
);
});
The above accomplishes the sequential Save + Upload, but fails to broadcast the saveDocumentSuccess action. What should I change?
Related, but perhaps it's another topic... I've read in a few places that it's best practice to limit Effects to one action. I'm not sure how this could be accomplished when you need to chain the result from one action/effect to the next. However, this would make it cleaner if there could be seperate Save and Upload effects. If someone has an idea on how to accomplish this, I'd be interested to know.
Thanks!
Upvotes: 0
Views: 489
Reputation: 414
IMO, there should be two effects in this scenario
this.documentService.saveDocument
and after success response, it should call another action(to trigger this.documentService.uploadDocument
through another effect) instead of chaining it to another switchMap.uploadDocument
. saveDocument$ = createEffect(() => {
return this.actions$.pipe(
ofType(DocumentActions.saveDocumentAction),
switchMap((action) =>
this.documentService.saveDocument(action.file).pipe(
map((res) => {
return new DocumentActions.uploadDocumentAction(res);
}),
catchError((error) =>
of(new DocumentActions.saveDocumentFailureAction(error))
)
)
)
);
});
uploadDocument$ = createEffect(() => {
return this.actions$.pipe(
ofType(DocumentActions.uploadDocumentAction),
switchMap((action) => {
this.documentService.uploadDocument(action.url).pipe(
map((res) => {
return new DocumentActions.uploadDocumentSuccessAction(res);
}),
catchError((error) =>
of(new DocumentActions.uploadDocumentFailureAction(error))
)
);
})
);
});
Upvotes: 1