Multiple file upload in Angular appending only one file

Issue

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

Answered By – Space Jam

Answer Checked By – Willingham (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.