2

I can't figure out how to download a file from the API using Angular. I sending a Blob from the backend but I don't think I convert it the right way since it gives me a serialization error. A bytearray however does give me the content of it but not as download.

This is my Java code:

@GetMapping("{id}")
public byte[] getExambyId(@PathVariable int id) {
    Exam exam = new Exam();
    byte[] file;
    try {
        exam = examRepository.findById(id).get();
        file = IOUtils.toByteArray(new FileInputStream(storageService.load(exam.getSkelet()).toFile()));
    } catch (NoSuchElementException e) {
        log.error("Exam with id: " + id + " not found.", this.getClass());
        return null;
    } catch (StorageFileNotFoundException e) {
        log.error("Cannot find examfile: " + exam.getSkelet() + ".", this.getClass());
        return null;
    } catch (FileNotFoundException e) {
        log.error("Cannot find file with filestream: " + exam.getSkelet() + ".", this.getClass());
        return null;
    } catch (IOException e) {
        log.error("IoException on: " + exam.getSkelet() + ".", this.getClass());
        return null;
    }
    return file;
}

This is my service in the frontend:

getExamSkeletById(id) {
  window.open(APIURL + '/' + id);
}
Sinan Samet
  • 6,432
  • 12
  • 50
  • 93

1 Answers1

2

I don't work with Java so I can't comment on whether your data coming from the server is correct. But in my Angular project I used the "file-saver" library off npm to trigger saving a PDF sent from my server. Then in my Angular code something to the effect of:

import * as FileSaver from 'file-saver';

downloadPDF() {
    this.http.get("api/endpoint/address", {withCredentials: true, responseType: "blob"}).subscribe(r => {
      var blob = r;
      FileSaver.saveAs(blob, "Filename.pdf");
    });
}

The this.http refers to HttpClient injected in the constructor of the component.

Keith Otto
  • 5,118
  • 2
  • 11
  • 7
  • Glad it worked. As a small followup one guess as to why the download wasn't working could possibly be you were missing some headers being sent from the server along with your byte array. I know there's things like the content-disposition and content-type headers that help tell the browser what the data is. Also content-length is useful to tell the browser how large the file is so you can get the progress indicator for the download. – Keith Otto May 25 '18 at 19:10