YSFKBDY
YSFKBDY

Reputation: 886

Angular image 404 fallback

I wrote a directive for images to show a placeholder for possible not existed images and it is working fine. When an image file not found, placeholder shows, but there is this log in console for not finding the image. I want to prevent it.

But I can't suppress GET 404 (Not Found) error in console. Is there any way to do it?

My directive:

@Directive({
    selector: 'img[imgFallback]'
})

export class ImageFallbackDirective implements OnDestroy {
    private _isApplied = false;
    private ERROR_EVENT_TYPE = 'error';
    private LOAD_EVENT_TYPE = 'load';
    private _targetImageElement: HTMLImageElement;
    private cancelOnError: () => void;
    private cancelOnLoad: () => void;
    
    srcFallback: string = "https://via.placeholder.com/120";
    @Output() wasLoaded = new EventEmitter<boolean>();

    constructor(private el: ElementRef, private renderer: Renderer2) {
        this._targetImageElement = el.nativeElement;

        this.onError = this.onError.bind(this);
        this.onLoad = this.onLoad.bind(this);

        this.addListeners();
    }

    ngOnDestroy() {
        this.removeErrorEvent();
        this.removeOnLoadEvent();
    }

    private onError() {
        this.srcIsFallback()
            ? this.setSrcToFallback()
            : this.removeOnLoadEvent();
    }

    private setSrcToFallback() {
        this._isApplied = true;

        this.setFallbackSrc();
    }

    private setFallbackSrc(isCustom?: boolean) {
        this.renderer.setAttribute(
            this._targetImageElement,
            'src',
            this.srcFallback
        );
    }

    private srcIsFallback() {
        return this._targetImageElement.getAttribute('src') !== this.srcFallback;
    }

    private onLoad() {
        this.wasLoaded.emit(this._isApplied);
    }

    private removeErrorEvent() {
        if (this.cancelOnError) {
            this.cancelOnError();
        }
    }

    private removeOnLoadEvent() {
        if (this.cancelOnLoad) {
            this.cancelOnLoad();
        }
    }

    private addListeners() {
        this.cancelOnError = this.renderer.listen(
            this._targetImageElement,
            this.ERROR_EVENT_TYPE,
            this.onError
        );

        this.cancelOnLoad = this.renderer.listen(
            this._targetImageElement,
            this.LOAD_EVENT_TYPE,
            this.onLoad
        );
    }
}

Upvotes: 0

Views: 839

Answers (1)

Andrei
Andrei

Reputation: 12036

sory, but there is no way to prevent these errors from leaking to console.

I would recommend you to use @HostListener to not to attach event listeners by hand.

@HostListener('error', ['$event.target'])
onError(imgElement) {
  // your logic
}

Upvotes: 1

Related Questions