0

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"
}]

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

Comments

0

Here is problem with this onSelectedFileMultiple method. Your setting a single value for imagePath, so when when you are trying to submit form it's holding only one file details.

Please try to change below code..

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);
        console.log(this.files);
      }
      event.target.value = '';
      this.productForm.get('imagePath').setValue(this.files);
    }
  }

Update :

set the event value to empty so that we can avoid object reference as well.

You can see more about this here how to reset <input type = "file">

2 Comments

I already tried doing this.files in place of this.files[i] before but it didn't help. In doing so nothing gets posted at all
try to set the event value to empty after the usage, updated answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.