14

my app got many images with descriptions. When user navigates these text is coming first and image is loading 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 spinner and track the image is loaded or not and display it?

Mujibur Rahman
  • 313
  • 1
  • 5
  • 17
  • https://webcake.co/a-loading-spinner-in-angular-2-using-ngswitch/ , check this maybe it will guide u.. – SeleM Jun 21 '16 at 08:21

4 Answers4

28

In your controller, add a function to 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 has 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 to http://angularjs.blogspot.com/2016/04/5-rookie-mistakes-to-avoid-with-angular.html to understand why and for a solution on how to apply it safely.

perezperret
  • 316
  • 2
  • 7
9

You dont need a function here, just add to your component:

imageLoader = true;

In template add 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 beacause actually a loading 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;" />
2

I think the most easiest way is to use the onError event on the img element. You can use it Like:

<img [src]="image.src" onError="this.src='assets/my/fancy/loader.gif';">
Sephen
  • 1,111
  • 3
  • 16
  • 38
  • 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. – d1fficult Jan 27 '21 at 10:47
1

The idea is to display the spinner by default, create a separate Image object that would be displayed when load 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);
null canvas
  • 10,201
  • 2
  • 15
  • 18