Angular (5) httpclient observe and responseType: ‘blob’

When using observe:response, don’t type the call (post<Blob>(...)), as the returned Observable will be of HttpResponse. So this should work:

this.httpclient.post('MyBackendUrl', 
    params,
    {observe: 'response', responseType: 'blob'}
);

Why this happens, is there’s two versions of the post method, one with a generic type, one without:

/**
     * Construct a POST request which interprets the body as JSON and returns the full event stream.
     *
     * @return an `Observable` of all `HttpEvent`s for the request, with a body type of `T`.
     */
    post<T>(url: string, body: any | null, options: {
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe: 'events';
        params?: HttpParams | {
            [param: string]: string | string[];
        };
        reportProgress?: boolean;
        responseType?: 'json';
        withCredentials?: boolean;
    }): Observable<HttpEvent<T>>;
    /**
     * Construct a POST request which interprets the body as an `ArrayBuffer` and returns the full response.
     *
     * @return an `Observable` of the `HttpResponse` for the request, with a body type of `ArrayBuffer`.
     */
    post(url: string, body: any | null, options: {
        headers?: HttpHeaders | {
            [header: string]: string | string[];
        };
        observe: 'response';
        params?: HttpParams | {
            [param: string]: string | string[];
        };
        reportProgress?: boolean;
        responseType: 'arraybuffer';
        withCredentials?: boolean;
    }): Observable<HttpResponse<ArrayBuffer>>;

you can use as like

responseType: 'blob' as 'json'

Other answers are right but they are missing the example.

The main answer first when the responseType is set the return type of the response is changed to Blob. To solve this add observe: 'response' which returns HTTPResponse.

Example:
I stumbled upon this issue and spent 6 hours solving.

So, here I present an example to get filename from headers and download the file:

downloadPDF(url: string): Observable<any> {
return this.http.get<any>(url, { responseType: 'blob', observe: 'response' }).pipe(
  map((result:HttpResponse<Blob>) => {
    console.log(result);
    saveAs(result, "Quotation.pdf");
    return result;
  }));

Here the http is instance of HttpClient, saveAs() is a method of FileSaver npm package same as the OP.

There is one more problem you might get only 5 headers(Cache-Control, Pragma, etc) in the result.headers and not your custom header for e.g. x-filename.

The reason behind this CORS. Basically CORS doesn’t allow browsers to access more than handfull of headers (listed in the link above).

So solve this you would have to change server/API to send Access-Control-Expose-Headers header with the request.