Search code examples
angularspring-boot

Downloading File from Spring into Angular Gives undefied result


I have a spring boot back end with the following code (downloads a png file):

  @GetMapping(value = "downloadsignature", produces = "image/png")
  public ResponseEntity downloadSignature(HttpServletRequest request) {
    var user = getUserOfRequest();
    try {
      var resource = signFileStorage.loadFileAsResource(user.getSignatureImageFile());
      return ResponseEntity.ok().contentType(MediaType.parseMediaType(request.getServletContext()
                                                                             .getMimeType(resource.getFile()
                                                                                                  .getAbsolutePath())))
                           .header(HttpHeaders      .CONTENT_DISPOSITION,
                                   "attachment; filename=\"" + resource.getFilename() + "\"")
                           .body(new InputStreamResource(resource.getInputStream()));
    } catch (Exception e) {
      logger.error(e.getMessage());
      return ResponseEntity.badRequest().body("error.signature_cannot_read");
    }
  }

And the corresponding Angular code is :

The service:

  public downloadSignature(): Observable<Blob> {
    return this.http.get<Blob>(`${this.getURL()}/downloadsignature`);
  }

and the usage code inside the component is :

  ngOnInit(): void {
    this.profileService
      .downloadSignature()
      .pipe(catchError((error) => of(this.processError(error))))
      .subscribe((item) => {
        console.log(item);
      });
  }

The result is always undefined in Angular. In Postman the response is the PNG image, in the network tab in Firefox's debug tools the response is the PNG image, but Angular always gives me undefined


Solution

  •   public downloadSignature(): Observable<Blob> {
        return this.http.get<Blob>(`${this.getURL()}/downloadsignature`);
      }
    

    You are only typing the response, doing nothing else. The default behavior is JSON.

    Try the following :

      public downloadSignature(): Observable<Blob> {
        return this.http.get(
          `${this.getURL()}/downloadsignature`, 
          { responsType: 'blob' }
        );
      }