DarkW1nter
DarkW1nter

Reputation: 2851

Angular 6 - catch missing image source then try to reset the same source

I have a list of blobs that a user can add to. If I have a newly added image hasn't finished uploading by the time the list is refreshed I catch the error as follows, and can see the function kicking off when it should:

<img src="https://MyUrl/thumbnails/{{ blob.name }}" width="125" id="MyImg"
        (error)="error()"/>

Is it possible to pass that image into the error function to retry setting the source?

Upvotes: 1

Views: 842

Answers (1)

Andrei Tătar
Andrei Tătar

Reputation: 8295

You can create a directive that binds src and retries (sets to null and again to the binded value with a timeout) on error. Here is for example something very similar to what you need and a very good starting point: https://medium.com/@sub.metu/angular-fallback-for-broken-images-5cd05c470f08

It basically uses a fallback url in case the src one fails.

Something like this (quickly modified, not tested):

import { Directive, OnDestroy, Input, ElementRef } from '@angular/core';

@Directive({
  selector: 'img[retrySrc]',
  host: {
    '(error)': 'loadError()',
    '(load)': 'clearTimer()',
  }
})
export class RetrySrcDirective implements OnDestroy {
  private _retrySrc: string;
  private _timer;

  constructor(
    private element: ElementRef<HTMLImageElement>,
  ) {
  }

  @Input()
  set retrySrc(value: string) {
    this.clearTimer();
    this._retrySrc = value;
    this.element.nativeElement.src = value; //each set on src triggers a new request in google Chrome
  }

  ngOnDestroy() {
    this.clearTimer();
  }

  loadError() {
    this.clearTimer();
    this._timer = setTimeout(() => this.element.nativeElement.src = this._retrySrc, 5000);
  }

  clearTimer() {
    if (this._timer) {
      clearTimeout(this._timer);
      delete this._timer
    }
  }
}

and you use it like:

<img [retrySrc]="'https://MyUrl/thumbnails/'+blob.name">

Alternatively you can do regular HttpClient requests periodically in the directive and set the src once you get a 200 response (use some default src meanwhile).

Upvotes: 3

Related Questions