I haven't been able to make any of the solutions to similar problems work for my case. I would like to load a pdf from filesystem with django and return it via an API call to Angular so that it can be displayed. My Django code is pretty much:
class LoadPdfViewSet(views.APIView):
def get(self, request):
# some code here here
response = FileResponse(open(path_to_pdf, 'rb').read())
response.headers = {
'Content-Type': 'application/pdf',
'Content-Disposition': 'attachment;filename="report.pdf"',
}
response.as_attachment = True
return response
while on the Angular side I have a service that does this:
export class LoadPdfService {
constructor(
private http: HttpClient
) {}
getPdf(): Observable<Blob> {
const params = new HttpParams({
fromObject: {
responsetype: 'arraybuffer'
// other stuff here
}
})
return self.http.get<Blob>(loadpdf_api_url, {params}).pipe(catchError(self.myErrorHandler))
}
}
and a component that tries to open the pdf like this:
export class MyComponent {
constructor(
public loadPdfService: LoadPdfService
) {}
download_pdf() {
let call = self.loadPdfService.getPdf();
call.subscribe( (response:Blob) => {
if (window.navigator && window.navigator.msSaveOrOpenBlob) { // for IE
window.navigator.msSaveOrOpenBlob(blob, "report.pdf");
} else {
let pdfUrl = URL.createObjectURL(blob)
window.open(pdfUrl, '_blank')
URL.revokeObjectURL(pdfUrl);
}
}
}
}
but nothing happens. I have also tried using different responses and passthrough renderers on the django side, and Observable<Response>
and .then()
callbacks like
response.arrayBuffer().then(buffer => new Blob([buffer], {type: 'application/pdf'}))
on the Angular side. Sometimes I have managed to get the new window/tab to open but no pdf could be displayed.
I finally figured it out. In the python part, the read()
can be removed with no problem. The issue was with the service response type and mapping of the response:
getPdf(): Observable<Blob> {
const options = {
params: new HttpParams({
fromObject: {
// my own parameters here
}
}),
responseType: 'blob' as 'json'
};
return this.http.get(this.url, options).pipe(
map(response => response as Blob),
catchError(this.myErrorHandler))
}