1

I have a Spring REST service which gives a byte array. Previously I was using angularjs 1. Using FileSaver, I was able to download the pdf which is sent from REST service on the the response of a HTTP POST call.

Now, I am migrating my changes to angular 5. This is my HTTP post call in service -

testPDF(abc: FormArray): Observable<HttpResponse<any>> {
    const options = {
        headers: new HttpHeaders({
            'Content-type': 'application/json',
             'response-type': 'blob'
       })
     }
     return this.http.post<HttpResponse<any>>('/myRestPath', abc, options);
}

On my component typescript file I have subscribed like this -

xyz() {
    this.myService.testPDF(this.abc.value).subscribe((file: any) => console.log('done'));
}

I have verified my REST service. It returns proper byte array. I have tried several other workarounds available on the internet. But nothing seems to be working. In browser console I could see the response, which looks to be a PDF in byte stream. In console I could see 3-4 MB size received, which make me believe that I have received the data but couldn't subscribe it. HTTP response code is also 200.

It looks like by default, the response is tried to be fetched as a JSON instead of BLOB. As my response doesn't start with '{', while parsing the data it couldn't parse the response. I am not asking anyone to write code for me. For downloading PDF file also, I can do it using FileSaver.

The key problem I am facing is why my application is not entering into the subscribe block and execute the console statement.

2
  • Show abc method of myService; Commented Mar 21, 2018 at 4:31
  • Sorry. My bad. Abc method is the testPDF one. I have updated the question. Commented Mar 21, 2018 at 4:34

1 Answer 1

2

Looks like you are setting the response type on the headers, but HttpClient expects it to be set on the responseType property of the options.

For HttpClient the following update would work

testPDF(abc: FormArray): Observable<HttpResponse<Blob>> {
    return this.http.post('/myRestPath', abc, {
        observe: 'response',
        responseType: 'blob' 
    });
}

A complete example which works for me with a GET, provided there is a PDF file with the name some.pdf under the assets directory.

import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class MyNewService {

  constructor(private http: HttpClient) { }

  getSomePDF():  Observable<HttpResponse<Blob>>{
    return this.http.get('/assets/some.pdf',  {
      observe: 'response',
      responseType: 'blob' 
    });
  }
}

For older ones using @angular/http, you can use the ResponseContentType enum with an import { ResponseContentType } from '@angular/http';

 const options = {
     responseType: ResponseContentType.Blob 
 }

API docs here.

Sign up to request clarification or add additional context in comments.

7 Comments

When I set response type like this, I am getting compilation error while setting options as a 3rd argument on http post. It's showing "Types of property 'responseType' are incompatible. Type 'string' is not assignable to type '"json'".
@pradiptagure updated answer to cover more versions of Angular.
Having the same issue still. It's still giving same compilation error.
I am using latest version of angular.
@pradiptagure can you check the latest update to the answer
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.