How to Upload multiple files in Angular 6 with ADDMORE button?
After trying with different scenarios to rendering the formdata object, I succeed in one scenario.
GitHub Link: Source
Updated files
multi-files-upload.component.html
<div class="container-fluid">
<section class="content">
<div id="main-form-content">
<form [formGroup]="documentGrp" (ngSubmit)="OnSubmit(documentGrp.value)" #uploadDocumentsForm="ngForm" ngNativeValidate>
<div class="box box-solid box-primary">
<div class="box-body" formArrayName="items">
<h2 class="page-header text-blue ">
<i class="fa fa-files-o"></i> Upload Documents
</h2>
<div class="row">
<div class="col-sm-12">
<div *ngFor="let item of items.controls; let i = index;">
<div [formGroupName]="i">
<table id="tbl-upload" class="table table-bordered">
<tbody>
<tr *ngIf="i==0" class="active">
<th>Document Name</th>
<th>Document Description</th>
<th>Document File</th>
<th> </th>
</tr>
<tr>
<td>
<div class="form-group required">
<input type="text" class="form-control" name="doc_name" formControlName="doc_name" placeholder="Enter document Category"
required="">
<div class="help-block"></div>
</div>
</td>
<td>
<div class="form-group ">
<input type="text" class="form-control" name="doc_description" formControlName="doc_description" maxlength="100" placeholder="Enter document related descriptions"
required="">
<div class="help-block"></div>
</div>
</td>
<td>
<div class="form-group required">
<input type="file" title="Browse Document" (change)="fileSelectionEvent($event,i)" required="">
<div class="help-block"></div>
</div>
</td>
<td class="remove" *ngIf=" i!=0 ">
<a title="Remove" (click)="removeItem(i)" class="fa fa-minus-square fa-lg text-red"></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="pull-right">
<button type="submit" class="btn btn-sm btn-success" title="Add More" style="" (click)="addItem()">Add More</button>
</div>
</div>
<!--./col-->
</div>
<!--./row-->
</div>
<!--./box-body-->
<div class="box-footer" style="align-content: center">
<button type="submit" class="btn btn-primary pull-right">Save</button>
</div>
</div>
</form>
</div>
</section>
</div>
multi-files-upload.component.ts
import { Component, OnInit, Renderer, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormArray, FormControl, NgForm } from '@angular/forms';
import { MultifilesService } from './multifiles.service'
@Component({
selector: 'app-multi-files-upload',
templateUrl: './multi-files-upload.component.html',
styleUrls: ['./multi-files-upload.component.css']
})
export class MultiFilesUploadComponent implements OnInit {
constructor(private renderer: Renderer,
private formBuilder: FormBuilder,
private multifilesService: MultifilesService
) { }
public documentGrp: FormGroup;
public totalfiles: Array<File> =[];
public totalFileName = [];
public lengthCheckToaddMore =0;
ngOnInit() {
this.documentGrp = this.formBuilder.group({
doc_name: '',
doc_description: '',
documentFile:new FormControl(File),
items: this.formBuilder.array([this.createUploadDocuments()])
});
}
createUploadDocuments(): FormGroup {
return this.formBuilder.group({
doc_name: '',
doc_description: '',
documentFile : File
});
}
get items(): FormArray {
return this.documentGrp.get('items') as FormArray;
};
addItem(): void {
//console.log("length is ",this.totalfiles.length);
//console.log("lengthCheckToaddMore ", this.lengthCheckToaddMore);
if(this.totalfiles.length!=0)
if( this.items.value[0].doc_name != "" && this.items.value[0].doc_description != "" && ((this.lengthCheckToaddMore) === (this.totalfiles.length)) )
{
this.items.insert(0, this.createUploadDocuments())
this.lengthCheckToaddMore=this.lengthCheckToaddMore+1;
}
}
removeItem(index: number) {
this.totalfiles.splice(index);
this.totalFileName.splice(index);
this.items.removeAt(index);
this.lengthCheckToaddMore=this.lengthCheckToaddMore-1;
// console.log("name are ",this.totalFileName);
}
public fileSelectionEvent(fileInput: any,oldIndex) {
//console.log("oldIndex is ", oldIndex);
if (fileInput.target.files && fileInput.target.files[0]) {
var reader = new FileReader();
reader.onload = (event: any) => {
}
if(oldIndex==0)
{
this.totalfiles.unshift((fileInput.target.files[0]))
this.totalFileName.unshift(fileInput.target.files[0].name)
}
else
{
this.totalfiles[oldIndex]=(fileInput.target.files[0]);
this.totalFileName[oldIndex]=fileInput.target.files[0].name
}
reader.readAsDataURL(fileInput.target.files[0]);
}
if(this.totalfiles.length == 1)
{
this.lengthCheckToaddMore=1;
}
}
public OnSubmit(formValue: any) {
let main_form: FormData = new FormData();
for(let j=0;j<this.totalfiles.length; j++)
{
console.log("the values is ",<File>this.totalfiles[j]);
console.log("the name is ",this.totalFileName[j]);
main_form.append(this.totalFileName[j],<File>this.totalfiles[j])
}
console.log(formValue.items)
//reverseFileNames=this.totalFileName.reverse();
let AllFilesObj= []
formValue.items.forEach((element, index) => {
console.log("index is ",index);
console.log("element is ", element);
let eachObj=
{
'doc_name' : element.doc_name,
'doc_description' : element.doc_description,
'file_name' : this.totalFileName[index]
}
AllFilesObj.push(eachObj);
});
//console.log("the Array data is ",AllFilesObj);
main_form.append("fileInfo",JSON.stringify(AllFilesObj))
this.multifilesService.saveFiles(main_form).subscribe(data => {
//console.log("result is ", data)
})
}
}
Multifiles.service.ts
same code already in the question section.
MultiFileController.java
@PostMapping("uploadFiles")
public String uploadMultiFiles(HttpServletRequest request)
{
System.out.println("hitting uploadFiles");
//System.out.println("data is "+ upladeedFiles);
List documentList= new ArrayList<>();
//System.out.println(request.getParameter("fileInfo"));
JSONArray jsonArray = new JSONArray(request.getParameter("fileInfo"));
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject jsonObj = jsonArray.getJSONObject(i);
documentList.add(jsonObj);
System.out.println("index "+ i +" -- "+jsonObj);
}
MultipartHttpServletRequest multiPartRequest = new DefaultMultipartHttpServletRequest(request);
try {
multiPartRequest = (MultipartHttpServletRequest) request;
multiPartRequest.getParameterMap();
Iterator<String> itr = multiPartRequest.getFileNames();
while (itr.hasNext()) {
MultipartFile mFile = multiPartRequest.getFile(itr.next());
System.out.println("FileName is "+mFile.getOriginalFilename());
// Do something with the mfile based on your requirement
}
} catch (Exception e) {
e.printStackTrace();
}
return "uploaded ";
}
If you don't understand the code please fork it to your repository then clone and debug with console logs then you can clearly understand the code. Thanks
SHIVA
Updated on August 02, 2022Comments
-
SHIVA over 1 year
Hello, Everone. I've been trying to Upload above(image) use case. I know it is very easy when we have a single file. but now the scenario is different it consists of an array of objects with the file. Now my question is how can I render the formdata object with the array of objects where each object consists of a file. For dynamic form, I used angular reactive forms. Can anyone please suggest me how can send whole data to the backed with the single click on save button. For backend I used Springmvc. Thanks in advance.
FullSource code availabe on my Github : Source
multi-files-upload.component.html
<div class="container-fluid"> <section class="content"> <div id="main-form-content"> <form [formGroup]="documentGrp" (ngSubmit)="OnSubmit(documentGrp.value)" #uploadDocumentsForm="ngForm" ngNativeValidate> <div class="box box-solid box-primary"> <div class="box-body" formArrayName="items"> <h2 class="page-header text-blue "> <i class="fa fa-files-o"></i> Upload Documents </h2> <div class="row"> <div class="col-sm-12"> <div *ngFor="let item of items.controls; let i = index;"> <div [formGroupName]="i"> <table id="tbl-upload" class="table table-bordered"> <tbody> <tr *ngIf="i==0" class="active"> <th>Document Name</th> <th>Document Description</th> <th>Document File</th> <th> </th> </tr> <tr> <td> <div class="form-group required"> <input type="text" class="form-control" name="doc_name" formControlName="doc_name" placeholder="Enter document Category" required=""> <div class="help-block"></div> </div> </td> <td> <div class="form-group "> <input type="text" class="form-control" name="doc_description" formControlName="doc_description" maxlength="100" placeholder="Enter document related descriptions" required=""> <div class="help-block"></div> </div> </td> <td> <div class="form-group required"> <input type="file" name="admission_docs_path" title="Browse Document" (change)="fileSelectionEvent($event)" required=""> <div class="help-block"></div> </div> </td> <td class="remove" *ngIf=" i!=0 "> <a title="Remove" (click)="removeItem(i)" class="fa fa-minus-square fa-lg text-red"></a> </td> </tr> </tbody> </table> </div> </div> <div class="pull-right"> <a class="btn btn-sm btn-success" title="Add More" style="" (click)="addItem()"> <i class="fa fa-plus-square"></i> Add More</a> </div> </div> <!--./col--> </div> <!--./row--> </div> <!--./box-body--> <div class="box-footer" style="align-content: center"> <button type="submit" class="btn btn-primary pull-right">Save</button> </div> </div> </form> </div> </section> </div>
multi-files-upload.component.ts
import { Component, OnInit, Renderer } from '@angular/core'; import { FormBuilder, FormGroup, Validators, FormArray, FormControl, NgForm } from '@angular/forms'; import { MultifilesService } from './multifiles.service' @Component({ selector: 'app-multi-files-upload', templateUrl: './multi-files-upload.component.html', styleUrls: ['./multi-files-upload.component.css'] }) export class MultiFilesUploadComponent implements OnInit { constructor(private renderer: Renderer, private formBuilder: FormBuilder, private multifilesService: MultifilesService ) { } public documentGrp: FormGroup; ngOnInit() { this.documentGrp = this.formBuilder.group({ doc_name: '', doc_description: '', documentFile: File, items: this.formBuilder.array([this.createUploadDocuments()]) }); } public doc_name = ""; public doc_description = ""; public documentFile: File; createUploadDocuments(): FormGroup { return this.formBuilder.group({ doc_name: '', doc_description: '', documentFile: File, }); } get items(): FormArray { return this.documentGrp.get('items') as FormArray; }; addItem(): void { this.items.insert(0, this.createUploadDocuments()) } removeItem(index: number) { this.items.removeAt(index); } public fileSelectionEvent(fileInput: any) { if (fileInput.target.files && fileInput.target.files[0]) { var reader = new FileReader(); reader.onload = (event: any) => { } this.documentFile = (fileInput.target.files[0]); console.log("the document is" + JSON.stringify(fileInput.target.files[0].name)); reader.readAsDataURL(fileInput.target.files[0]); } } public OnSubmit(formValue: any) { let total_form: FormData[] = []; console.log(formValue.items) formValue.items.forEach(element => { let upl_fom: FormData = new FormData(); console.log("each element is", element); upl_fom.append('document_category', element.doc_name); upl_fom.append('document_details', element.doc_description); upl_fom.append('document_file', element.documentFile); total_form.push(upl_fom); }); this.multifilesService.saveFiles(total_form).subscribe(data => { console.log("result is ", data) }) } }
Multifiles.service.ts
import { Injectable } from '@angular/core'; import { HttpClient,HttpHeaders } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class MultifilesService { constructor( private http: HttpClient) { } saveFiles(total_form) { return this.http.post("http://localhost:8181/uploadFiles",total_form); } }
UploadController.java
@PostMapping("uploadFiles") public String uploadMultiFiles(HttpServletRequest request) { System.out.println("hitting uploadFiles"); Enumeration e =request.getParameterNames(); while(e.hasMoreElements()) { System.out.println(e.nextElement()); } MultipartHttpServletRequest multiPartRequest = new DefaultMultipartHttpServletRequest(request); try { multiPartRequest = (MultipartHttpServletRequest) request; multiPartRequest.getParameterMap(); //multipartRequest. Iterator < String > it = multiPartRequest.getFileNames(); int i = 1; while (it.hasNext()) { MultipartFile multipart = multiPartRequest.getFile(it.next()); System.out.println("File name is "+multipart.getOriginalFilename()); } }catch(Exception ex) { } return "uploaded "; }
-
Chellappan வ almost 6 yearswhat is the issue now?
-
SHIVA almost 6 years@Chellappan I didn't get any files to my backend so i am assuming the rendering of formdata in my component.ts may be an issue.so I want to know how to render the formdata object when this type of scenario.
-
Joseph Webber almost 6 yearsDon't add "SOLVED" to the title, just accept your answer and it being solved will be implied.
-