1
votes

I have a backend that returns an image. I can call this backend fine in the browser. The image gets displayed, all OK.

The response type is image/jpeg.

Now, I'm investigating options for how I can fetch the image using Angular HttpClient.

If I try to just issue a GET call, I can see the image downloaded fine in the Network tab of the browser.

Angular, however, gives me an error: enter image description here

Code:

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

@Injectable({
  providedIn: 'root'
})
export class ThumbnailService {
  private thumbnailUrl = 'http://localhost:8080/thumbnail';

  constructor(private http: HttpClient) { }

  public findOne(classifiedId: number): Observable<any> {
    const httpOptions = {
      headers: new HttpHeaders({
        'Accept': 'image/jpeg',
      })
    };
    return this.http.get<any>(`${this.thumbnailUrl}/${classifiedId}`, httpOptions);
  }
}

From what I understand...

  • Angular tries to parse the response as JSON because of the type
  • There are lots of overloaded methods available for how to parse the response, depending on how I type the response
  • If I use Blob as return type:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ThumbnailService {
  private thumbnailUrl = 'http://localhost:8080/thumbnail';

  constructor(private http: HttpClient) { }

  public findOne(classifiedId: number): Observable<any> {
    const httpOptions = {
      headers: new HttpHeaders({
        'Accept': 'image/jpeg',
      })
    };
    return this.http.get<Observable<Blob>>(`${this.thumbnailUrl}/${classifiedId}`, httpOptions);
  }
}

I get the same error.

Looking at the Blob type, it seems to have some structural expectations that I don't currently fulfill...

Is there a simple(r) way to fetch an image using Angular HttpClient? Am I missing something?

Setting the headers along with setting responseType results in compilation error, both with response typed as any and as Blob:

Argument of type '{ headers: HttpHeaders; responseType: string; }' is not assignable to parameter of type '{ headers?: HttpHeaders | { [header: string]: string | string[]; }; observe?: "body"; params?: HttpParams | { [param: string]: string | string[]; }; reportProgress?: boolean; responseType?: "json"; withCredentials?: boolean; }'. Types of property 'responseType' are incompatible. Type 'string' is not assignable to type '"json"'.

2
You should set responseType as 'blob' to fetch the image as Blob. Refer - angular.io/api/common/http/HttpRequest#responseTypeuser2216584

2 Answers

3
votes

You are only type casting to Blob, not actually parsing it as a Blob. If you want angular to parse it as a Blob, you have to set the responseType accordingly.

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

@Injectable({
  providedIn: 'root'
})
export class ThumbnailService {
  private thumbnailUrl = 'http://localhost:8080/thumbnail';

  constructor(private http: HttpClient) { }

  public findOne(classifiedId: number): Observable<any> {
    const httpOptions = {
      headers: new HttpHeaders({
        'Accept': 'image/jpeg',
      }),
      responseType: 'blob' // This tells angular to parse it as a blob, default is json
    };
    return this.http.get<Observable<Blob>>(`${this.thumbnailUrl}/${classifiedId}`, httpOptions);
  }
}

Example StackBlitz

0
votes

For receiving the BLOB in the response you have to pass a responseType parameter into the HTTP get method. Here are the available overloads of Angular HttpClient get method Http Get-Angular check the overload#5.