How to load image with spinner in Angular2
Asked Answered
G

4

15

My app has many images with descriptions. When user navigates, the text appears first and the image loads with some delay. I would like to add a spinner here. A directive which shows spinner while loading the image and shows image like:

<myimgdir [src]='myimage.png'></myimgdir>

How to add the spinner, track image loading, and display it accordingly?

Gurgitation answered 21/6, 2016 at 5:44 Comment(1)
webcake.co/a-loading-spinner-in-angular-2-using-ngswitch , check this maybe it will guide u..Brentonbrentt
H
31

In your controller, add a function to handle the onLoad event, setting the state to {loading: false}:

loading: boolean = true
onLoad() {
    this.loading = false;
}

In your template, render a loading GIF (or whatever you want) while the state is loading === true. The tricky part is that you should just hide the img element with [hidden]="true/false" as opposed to prevent it from rendering so it will actually load the src, then just bind the onLoad function in your controller to the (load) event on the actual image:

<img *ngIf="loading" src="/assets/loading.gif" alt="loading" />
<img [hidden]="loading" (load)="onLoad()" src="{{ source }}" />

This solution is functionally the same as AngJobs's, but it's more declarative and a little less cumbersome IMO.

PS: Using [hidden]="boolean" instead of *ngIf is a bit of a gotcha, you should look here to understand why and for a solution on how to apply it safely.

Horrocks answered 8/8, 2016 at 20:4 Comment(4)
Your 2nd code block looks weird. You seem to pass angular bindings to a img(...) function call.Sherman
@GünterZöchbauer That's a mistake, I didn't clarify I was using jade/pug syntax. That block you mention is markup, not JavaScript, I will edit it to use HTML syntaxHorrocks
I see. Never used that myself.Sherman
Do you think this could be a directive you use on multiple images?Guttering
V
9

You don't need a function here, just add the following to your component:

imageLoader = true;

In template, add the following:

<div [hidden]="!imageLoader">Loading...</div>
<img [hidden]="imageLoader" src=".../image.png" (load)="this.imageLoader = false;" />

As you see, there is text instead of a GIF because actually an animation GIF also must be loaded. In some cases, this could take much more time than loading the image itself.

If the GIF is loaded already, you can use:

<img [hidden]="!imageLoader" src=".../loading_spinner.gif" />
<img [hidden]="imageLoader" src=".../image.png" (load)="this.imageLoader = false;" />
Vitality answered 22/5, 2018 at 7:32 Comment(0)
L
2

I think the easiest way is to use onError event on the img element:

<img [src]="image.src" onError="this.src='assets/my/fancy/loader.gif';">
Linderman answered 22/1, 2017 at 13:46 Comment(1)
But in this case no default image can be rendered if the image load fails, the spinner will continue spinning. Goal is to show gif or spinner untill the loading completes.Pneumatology
S
1

The idea is to display the spinner by default. Create a separate Image object that would be displayed when loading is complete.

var img = new Image();

/// set handler and url
img.onload = onloadHandler;
img.src = imageURLs[i];

/// if image is cached IE (surprise!) may not trigger onload
if (img.complete) onloadHandler().bind(img);
Shameful answered 21/6, 2016 at 8:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.