TypeError: res.blob is not a function
16,378
Use the res.body
instead of res
while constructing the Blob
.
downloadPDF(): any {
return this.http.get(environment.api.urls.downloads.getPdf, {
responseType: 'blob'
})
.pipe(
map((res: any) => {
return new Blob([res.body], {
type: 'application/pdf'
})
})
);
}
Author by
Peter Penzov
Updated on July 17, 2022Comments
-
Peter Penzov almost 2 years
I want to implement file download using this Angular 6 code:
Rest API:
private static final Logger LOG = LoggerFactory.getLogger(DownloadsController.class); @GetMapping(path="export") public ResponseEntity<byte[]> export() throws IOException { File pdfFile = Paths.get(EXTERNAL_FILE_PATH).toFile(); byte[] fileContent = Files.readAllBytes(pdfFile.toPath()); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/pdf")); // Here you have to set the actual filename of your pdf String filename = "output.pdf"; headers.setContentDispositionFormData(filename, filename); headers.setCacheControl("must-revalidate, post-check=0, pre-check=0"); ResponseEntity<byte[]> response = new ResponseEntity<>(fileContent, headers, HttpStatus.OK); return response; }
Service:
import {Injectable} from '@angular/core'; import {HttpClient, HttpParams} from "@angular/common/http"; import {Observable} from "rxjs/index"; import {environment} from "../../../environments/environment"; import {HttpUtils} from "../common/http-utils"; import { map } from 'rxjs/operators'; import {Http, ResponseContentType} from '@angular/http'; @Injectable({ providedIn: 'root' }) export class DownloadService { constructor(private http: HttpClient) { } downloadPDF(): any { return this.http.get(environment.api.urls.downloads.getPdf, { responseType: 'blob' }) .pipe( map((res: any) => { return new Blob([res.blob()], { type: 'application/pdf' }) }) ); } }
Component:
import {Component, OnInit} from '@angular/core'; import {DownloadService} from "../service/download.service"; import {ActivatedRoute, Router} from "@angular/router"; import {flatMap} from "rxjs/internal/operators"; import {of} from "rxjs/index"; import { map } from 'rxjs/operators'; @Component({ selector: 'app-download', templateUrl: './download.component.html', styleUrls: ['./download.component.scss'] }) export class DownloadComponent implements OnInit { constructor(private downloadService: DownloadService, private router: Router, private route: ActivatedRoute) { } ngOnInit() { } export() { this.downloadService.downloadPDF().subscribe(res => { const fileURL = URL.createObjectURL(res); window.open(fileURL, '_blank'); }); } }
The file is present in the directory but when I try to download it I get error:
ERROR TypeError: res.blob is not a function at MapSubscriber.project (download.service.ts:24) at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:35) at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54) at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:41) at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54) at FilterSubscriber.push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterSubscriber._next (filter.js:38) at FilterSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54) at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber.notifyNext (mergeMap.js:84) at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:15) at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
Do you know how I can fix this issue? Do I need to add additional configuration in order to download the file via Angular web UI?
I use spring-boot-starter-parent version 2.1.0.RELEASE and angular 6
Update: I tested this but nothing happens:
downloadPDF(): any { return this.http.get(environment.api.urls.downloads.getPdf, { responseType: 'blob' }) .pipe( map((res: any) => { return new Blob([res], { type: 'application/pdf' }) }) ); }
-
Peter Penzov over 5 yearsIt's correct. I suppose that something is missing into the typescript code?
-
Peter Penzov over 5 yearsAny other ideas?
-
Sunil Singh over 5 yearstry once with
res._body
instead ofres.body