window.URL.createObjectURL [Angular 7 / Typescript]

Viewed 12745

I've to show/download a .pdf file in my Angular 7 project but I'm having some troubles with window.URL.createObjectURL. This is what I made:

this.userService.getFile(report.id).subscribe(
  res => {
    console.log(res)
    const filename = res.headers.get('content-disposition').split(';')[1].split('=')[1].replace(/\"/g, '')
    const blob = new Blob([res.body], { type: res.body.type })
    const url = window.URL.createObjectURL(blob)
    const a: HTMLAnchorElement = document.createElement('a') as HTMLAnchorElement

    a.href = url
    a.download = filename
    window.document.body.appendChild(a)
    a.click()
    window.document.body.removeChild(a)
    URL.revokeObjectURL(url)
  },
  err => {
    console.log(err)
  }

where getFile() is a simple http request

getFile(fileId: string): Observable<any> {
   return this.http.get(environment.API_URL + '/file/' + fileId, {observe: 'response', responseType: 'blob'})
}

My IDE is also firing a 'Instance member is not accessible' on window.URL.createObjectURL()

File seems to be fetched from server and from console I can see the debug print 'Navigate to blob://' but then download prompt does not shows up.

I've used the same approach in another Angular project (but version 6) and it works nice, I can't understand why now is not working anymore. Any suggestion?

Thank you!

3 Answers

I had a similar problem. Leaving out the window fixed it for me. For reference my full code is:

export class DownloadComponent {
  @Input() content: any;
  @Input() filename = 'download.json';

  download() {
    const json = JSON.stringify(this.content);
    const blob = new Blob([json], {type: 'application/json'});
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = this.filename;
    link.click();
  }
}

you should consider items below:

1- Be sure your Blob is valid By:

console.log(myBlob instanceof Blob); //true

if not use Blob constructor to make your Blob.

2- use URL.createObjectURL(Blob) without 'window':

const blobUrl = URL.createObjectURL(myBlob);

3- Bypass Angular DomSanitizer (XSS) Security By:

const safeblobUrl =  this.sanitizer.bypassSecurityTrustResourceUrl(blobUrl);

now you can use this URL in binding:

<audio [src]="safeblobUrl"></audio>

Here is a workable version of mine.

let link = document.createElement('a');
link.target = '_blank';
link.href = window.URL.createObjectURL(blob);
link.setAttribute("download", fileName);
link.click();
Related