Angular File multiple upload with no duplicates

Viewed 821

I'm new to angular , and I'm learning how to upload multiple files to my server. So what I've been able to do is that I can upload files, display a spinner then display that files under the upload button .

component.html :

 <div fxFlex="50" class="mb-24" *ngIf="show">
        <button mat-raised-button color="primary" (click)="hiddenfileinput.click()" fxFlex="50">
           <mat-icon>cloud</mat-icon>
           load documents
        </button>
     <input type="file" id="fileUpload" name="fileUpload" multiple (change)="onUpload($event)"   #hiddenfileinput style="display:none;"/>
 </div>
  <div *ngIf="!isLoading ; else loadBlock">
          <div *ngFor="let file of viewFiles">
               <span><mat-icon>attachment</mat-icon>{{file}}</span>  
          </div> 
                                    
  </div>
  <ng-template #loadBlock>
        <mat-spinner [diameter]="20"></mat-spinner>
  </ng-template>

Component.ts UploadFunction :

  viewFiles : string[]= [];
  isLoading = false; 
  files: FormData = new FormData(); 

onUpload(event)
  {
    this.isLoading = true;
    const fdata = event.target.files;


    for (let i = 0; i < fdata.length; i++) 
    {
       this.files.append('file[]', fdata[i], fdata[i].name);
    }
     for (var pair of this.files.values()) 
    {
     this.viewFiles.push(pair.name);
    }
 setTimeout(() => {
      this.isLoading = false
    },2500)
}

So here's the problem what if the user clicks the upload button , uploads 1 file and then clicks again on the button and uploads the same file and 3 others files, then I ll have a duplicated file on the list , how can I check if the file already exists ? or avoid duplicated files ?

Thanks !

EDIT

Found a working solution :

this.isLoading = true;
    const fdata = event.target.files;

    for (let i = 0; i < fdata.length; i++) 
    {
      for (var pair of this.files.values()) 
      {
       if(pair.name == fdata[i].name)
       {
         this.fileExists = true;
       }
      }

   if (!this.fileExists) {
     this.files.append('file[]', fdata[i], fdata[i].name);
     this.viewFiles.push(fdata[i].name);
   }
2 Answers

You can always check for duplicates, based on the file name, before appending a file to this.files:

for (let i = 0; i < fdata.length; i++) 
{
   // check if fdata[i].name already exists in this.files
   const fileExists = false;
   for (var pair of this.files.values()) { 
     if (pair.name == fdata[i].name) { 
       this.fileExists = true; 
     } 
   } 
   if (!fileExists) {
     this.files.append('file[]', fdata[i], fdata[i].name);
   }
}

You can also do a second check of the modified time to compare if the file is the same

  /**
   * values has changed
   */
  public onInputChange(event: Event): void {
    const newFiles: FileList = (<HTMLInputElement>event.target).files;
    this.value = this.value || [];

    // add only unique files
    for (const file of Array.from(newFiles)) {
      if (this.isSameNameAndModified(file)) {
        this.value.push(file);
      }
    }
    this.onChanged(this.value);
  }

  /**
   * unique based on name and modified
   */
  private isSameNameAndModified(file: File): boolean {
    for (const { name, lastModified } of this.value) {
      if (file.name === name && file.lastModified === lastModified) {
        return false;
      }
    }
    return true;
  }

Related