2

I have an Angular 5 project.

I need to display images in the UI that are fetched from the back end (say for example I want to display users' avatars in the upper toolbar, like in the SO toolbar above).

The back end is a REST server that serves images when invoked on some end-point.

I cannot seem to GET the images from the back end. And I am sure that the back end works.

I have try to do the following (based on this article):

Here is my service image.service.ts (boiler plate has been removed)

getImage(url: string): Observable<Blob> {
  return this.httpClient.get(`${url}`, {responseType: 'blob'})
}

Here is my coponent image.component.ts

@Component({
  selector: 'app-image',
  templateUrl: './image.component.html',
  styleUrls: ['./image.component.css']
})
export class ImageComponent implements OnInit {
  @ViewChild('myImage') image: ElementRef

  constructor(private imageService: ImageService) {}

  ngOnInit() {
    this.getMyImage('http://my-super-host:3000/images/super-hero.png')
  }

  getMyImage(url: string): void {
    this.imageService.getImage(url)
      .subscribe(response => this.image.nativeElement.src = window.URL.createObjectURL(response))
  }
}

And eventually, here is my image.component.html

<img #myImage>

In the browser's console, there is an error message saying that

ERROR TypeError: _this.image is undefined

This solution doesn't work. What am I missing here?

avi.elkharrat
  • 6,100
  • 6
  • 41
  • 47
  • 6
    Any reason why you're not using `` ? – Jeremy Thille Mar 21 '18 at 16:15
  • 1
    Alternatively, you could use base64 string as the image. Something like this: https://stackoverflow.com/a/8499716/193634 – Rosdi Kasim Mar 21 '18 at 16:30
  • @Jeremy Thille because I haven't met you before? No, seriously, is it secure to do so? – avi.elkharrat Mar 21 '18 at 16:42
  • Is the img tag rendered conditionally, eg. inside an *ngIf ? That's the most common reason why ViewChild doesn't work, because the element doesn't exist at component init time. A [src] binding might do it. – funkizer Mar 21 '18 at 16:44

2 Answers2

1

Adding a simple

<img src={{url}}>

did the trick.

From then, you may add *ngIf, class, alt... as needed.

avi.elkharrat
  • 6,100
  • 6
  • 41
  • 47
0

Another slightly different solution by someone else is discussed at:

[https://medium.com/techinpieces/blobs-with-http-post-aand-angular-5-a-short-story-993084811af4][1]

Based on that, I wrote code that works with Angular 7, some of which is below. See the link above for more info.

 getBlob_withQueryParams(imageUrl: string, params: HttpParams):  Rxjs.Observable<Blob> {
     const headers = new HttpHeaders({
       'Content-Type': 'application/json',
       'Accept': 'application/json'
     });
    return this._http.get<Blob>(imageUrl, {headers: headers, params: params, responseType: 'blob' as 'json' });
  }
user2367418
  • 196
  • 1
  • 5