I am trying to save files along with FormData in Angular 5. I can get the single file, but have no idea how to get all the files uploaded. I have three image files and input
Here's how I handle multiple files from a single file input. My component gathers the form data, and produces a Data object, which does not contain the files. It then calls this service method with the Data object and the files, which sends the data and the files in a multipart post.
save(data: Data, filesForUpload: File[]): Observable<Data> {
const formData = new FormData();
// add the files
if (filesForUpload && filesForUpload.length) {
filesForUpload.forEach(file => formData.append('files', file));
}
// add the data object
formData.append('data', new Blob([JSON.stringify(data)], {type: 'application/json'}));
return this.http.post<Data>(this.apiUrl, formData);
}
So, to handle two file inputs, you could do this:
save(data: Data, filesA: File[], filesB: File[]): Observable<Data> {
const formData = new FormData();
// add the files
if (filesA && filesA.length) {
filesA.forEach(file => formData.append('filesA', file));
}
if (filesB && filesB.length) {
filesB.forEach(file => formData.append('filesB', file));
}
// add the data object
formData.append('data', new Blob([JSON.stringify(data)], {type: 'application/json'}));
return this.http.post<Data>(this.apiUrl, formData);
}
Which would give you three parts in your multipart post, one for each set of files, and one for the data object.
This is what I tried and it worked as expected :
handleCategoryBanner(files: FileList) {
this.category.category_banner = '/categories/download/' + files[0].name;
this.formData.append('category_banner', files[0], files[0].name);
this.categoryContainersService.uploadFile(this.formData).subscribe(filename => console.log(files[0].name));
}
<div class="col-lg-12 text-center">
<input type="file" (change)="handleCategoryBanner($event.target.files)" class="custom-file-input" id="category_banner" accept=".jpeg,.png,.jpg">
<input type="hidden" name="category_banner" [(ngModel)]="category.category_banner" />
<label class="custom-file-label" for="customFile">Banner</label>
</div>
Try this code:
handleFileInput(files){
for (let j = 0; j < files.length; j++) {
let data = new FormData();
let fileItem = files[j]._file;
console.log(fileItem.name);
data.append('file', fileItem);
}
}
just put 'multiple' attribute on your input tag now by selecting 2 or more files on browsing you will get object should iterate on it to extract images on it. like this-->
<div class="form-group">
<label for="file">Choose File</label>
<input type="file" id="file" (change)="handleFileInput($event.target.files)" multiple>
</div>
I recently had a similar issue. This can be solved by setting the content type of header as null in the Angular code. Attaching the code snippet of Angular5 and spring boot backend.
let headers = new HttpHeaders();
//this is the important step. You need to set content type as null
headers.set('Content-Type', null);
headers.set('Accept', "multipart/form-data");
let params = new HttpParams();
const formData: FormData = new FormData();
for (let i = 0; i < this.filesList.length; i++) {
formData.append('fileArray', this.filesList[i], this.filesList[i].name);
}
formData.append('param1', this.param1);
formData.append('param2', this.param2);
this.http.post(this.ROOT_URL + this.SERVICE_ENDPOINT, formData, { params, headers }).subscribe((res) => {
console.log(res);
});
In the spring boot backend, you need to have the controller as -
@RequestMapping(value = "/uploadAndSendEmail", method = RequestMethod.POST, consumes= "multipart/form-data")
public ResponseEntity<String> uploadAndSendEmail(@RequestParam("fileArray") MultipartFile[] fileArray,
@RequestParam(value = "param1", required = false) String param1,
@RequestParam(value = "param2", required = false) String param2) {
//do your logic
}