Home > other >  Displaying preview of multiple selected files in Angular
Displaying preview of multiple selected files in Angular

Time:10-24

I am kind of new to Angular and right now I am trying to select multiple files and display their preview before uploading them to server.

My below code works fine if there are multiple files but selected separately, hovewer while trying to select multiple images at once, only the last one is rendered. I checked with console.log and while selecting multiple files at once the reader.result of the previous files except the last one is always null ever though the reader.onload is executing (the object is also inserted into the array, but without the image url).

I want to be able to also remove the selected files, so both files and their imagesUrl are kept in an FileWithImage object to keep the right order of their previews.

component.ts:

onFilesSelected(event: any): void {
    this.selectedFiles = event.target.files;

    for (let i = 0; i < this.selectedFiles.length; i  ) {

      let fileWithImage: FileWithImage = {
        imageUrl: '',
        file: this.selectedFiles[i],
      };

      var reader = new FileReader();
      reader.readAsDataURL(fileWithImage.file);

      reader.onload = (event) => {
        fileWithImage.imageUrl = reader.result;

        console.log(fileWithImage.file.name);
        console.log(fileWithImage.imageUrl);
        
        this.filesWithImages.push(fileWithImage);
      };
    }
  }

component.html (selecting and displaying images):

   <button
      type="button"
      mat-raised-button
      (click)="fileInput.click()"
      
    >
      Choose File
    </button>
    <input
      hidden
      (change)="onFilesSelected($event)"
      #fileInput
      type="file"
      accept="image/*"
      multiple="multiple"
    />
    <div *ngFor="let file of filesWithImages" >
      <img
        [src]="file.imageUrl"
        height="10%"
        width="10%"
        *ngIf="file.imageUrl"
      />
    </div>

I tried blocking the loop untill the reader.onload is executed with a use of a flag, but it did not work. I also tried to get the url directly from a method:

createImageUrl(file: File): any {
    var reader = new FileReader();
    reader.readAsDataURL(file);

    reader.onload = (event) => {
      return reader.result;
    };
  }

and call it in [src] of an image tag in html, but it made my program crash.

The main problem is probably why the result of reader is null for the first few files and only the last one is properly displayed. Can someone help me to find the cause of this problem?

CodePudding user response:

Try changing reader variable to local scope.

Change

var reader = new FileReader();

to

let reader = new FileReader();
  • Related