javascriptarraysangulartypescriptangular-file-upload

Multiple file upload in Angular appending only one file


I'm facing a problem with multiple files upload in my Angular application. Here I am trying to append the multiple files in onSelectedFileMultiple($event) but only one file is selecting and if I choose another file it is getting replaced with the new file but the actual expectation is they need to append each other and using post method I need to pass the JSON data of all the files that is being selected.

typescript:

productForm: FormGroup;
 public imagePath;
 public files = [];
constructor(public productService: ProductService, private formBuilder: FormBuilder) { }
  ngOnInit() {

    this.productForm = this.formBuilder.group({
      imagePath: ['']
   })
  }

  public onSelectedFileMultiple(event) {
    if (event.target.files.length > 0) {
      for (let i = 0; i < event.target.files.length; i++) {
        let file = event.target.files[i]
        this.files.push(file)
        this.productForm.get('imagePath').setValue(this.files[i]);
        console.log(this.files)
      }
    }
  }
public onProductSubmit(): any {

    const formData = new FormData();
    formData.append('imagePath', this.productForm.get('imagePath').value);
    //checking value of imagePath after appending to formData
    for (var pair of formData.entries()) {
      console.log(pair[0] + ': ' + pair[1]);  //returning value as imagePath: [object FileList]
    }

   this.httpClient.post('http://localhost:4000/api/v1' + '/post-product', formData);

HTML:

<form fxLayout="row wrap" [formGroup]="productForm" (ngSubmit)="onProductSubmit()" enctype="multipart/form-data">
<div fxFlex="100" fxFlex.gt-sm="100" class="px-1" ngClass.sm="mt-1" ngClass.xs="mt-1" method="post">
              <label>Upload Image</label>
              <mat-form-field class="w-100 form-group">
              <ngx-mat-file-input multiple type="file" formControlName="imagePath" name="imagePath" placeholder="PDF file only" (change)="onSelectedFileMultiple($event)" [accept]="'application/x-zip-compressed,image/*'"></ngx-mat-file-input>
              <mat-icon class="btn-project" mat-raised-button color="accent">folder</mat-icon>
            </mat-form-field>
            </div>
<div class="button-wrap" fxFlex="100" fxFlex.gt-sm="100" class="px-1" ngClass.sm="mt-1" ngClass.xs="mt-1">
              <button class="btn-project" mat-raised-button color="accent" type="submit">Post Product</button>
            </div>
          </form>

Expected JSON:

[{
   "attachmentName": "file1.txt",
   "attachedFile": "https://mean-ecom.s3.ap-south-1.amazonaws.com/1597294401122"
},
{
  "attachmentName": "image2.jpg",
   "attachedFile": "https://mean-ecom.s3.ap-south-1.amazonaws.com/1597294403496"
}]

Solution

  • The problem with your code is that you only append a single file to the formData. What you could do is to just loop through your files array and append every file in that array to the formData.

    So you would have to change this:

    public onProductSubmit(): any {
    
        const formData = new FormData();
        formData.append('imagePath', this.productForm.get('imagePath').value);
        //checking value of imagePath after appending to formData
        for (var pair of formData.entries()) {
          console.log(pair[0] + ': ' + pair[1]);  //returning value as imagePath: [object FileList]
        }
    
       this.httpClient.post('http://localhost:4000/api/v1' + '/post-product', formData);
    }
    

    To this:

    public onProductSubmit(): any {
    
        const formData = new FormData();
        files.forEach(file => {
           formData.append('files[]', file, file.name);
        })
    
       this.httpClient.post('http://localhost:4000/api/v1' + '/post-product', formData);
    }
    

    Stackblitz