'Angular 11 rxjs how to handle error in one of the request in mergemap inside forkjoin

I have the following method which does

  1. uploads an attachment and get attachmentid
  2. and make api call to get the blob of the attachment id to preview
private uploadAttachments(): void {
    this.spinnerService.show();
    forkJoin(
      Array.from(this.newlyAddedFiles).map((file) => {
        const fileName = file.name;
        return this.convertFile(file).pipe(
          mergeMap((convertedFile) =>
            this.uploadService
              // -->There is an 404 bad request here. how to catch and handle this. Currently it goes inside concatMap below
              .uploadAttachment({
                fileName: convertedFile.fileName,
                data: convertedFile.data,
              })
              .pipe(
                catchError((err) => {
                  console.log('err uploading', err);
                  return throwError(err);
                })
              )
          ),
          concatMap((uploadResult: UploadAttachmentResponse) => {
            const attachmentId = uploadResult.attachmentId;
            return this.uploadService.getBlob(attachmentId).pipe(
              map(
                (blob) =>
                  ({
                    fileName,
                    attachmentId,
                    imageURL: this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(blob)),
                    canPreview: blob?.size !== 0,
                  } as AttachmentUploadResult)
              ),
              catchError(() =>
                of({
                  fileName,
                  attachmentId,
                } as AttachmentUploadResult)
              )
            );
          })
        );
      })
    )
      .pipe(
        takeUntil(this.destroy$),
        finalize(() => this.spinnerService.hide())
      )
      .subscribe((newAttachments) => {
        this.uploadedAttachments?.map((existingAttachment) => (existingAttachment.isPreviouslyLinked = true));
        this.uploadedAttachments = this.uploadedAttachments.concat(newAttachments);
        this.onFilesUploaded.emit(this.uploadedAttachments);
      });
  }


Solution 1:[1]

You need to do two things

  1. don't rethrow the error, but return an observable indicating the error
  2. add a filter to the pipe before the concatMap so the error result does not propagate
          ...
          mergeMap((convertedFile) =>
            this.uploadService
              .uploadAttachment({
                fileName: convertedFile.fileName,
                data: convertedFile.data,
              })
              .pipe(
                catchError((err) => {
                  console.log('err uploading', err);
                  const subject = new Subject();
                  subject.next({error:err})
                  return subject; // this is where you would handle the error
                })
              )
          ),
          filter((result:any) => !result.error), // stop when there is an error
          map((result:any) => <UploadAttachmentResponse>result), // cast to the correct type when there is no error, if necessary
          concatMap((uploadResult: UploadAttachmentResponse) => {
          ...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 The Fabio