I am trying to build a form in Angular 6 that offers a file selection box that allows the user to select multiple files (Stackblitz: https://stackblitz.com/edit/angular-yjummp).
The Template looks like:
<form [formGroup]="form">
<input id="files" formControlName="files" type="file" accept="image/*,video/*" multiple (change)="onFilesChanged($event)"/>
</form>
I am building the form in TypeScript like this:
public form = new FormGroup({
files: new FormControl('')
});
public onFilesChanged(event: any): void {
console.log(event.target.files);
console.log(this.form.value);
}
Now, in the onFilesChanged
Handler, the selected files can be correctly retrieved from the event by accessing event.target.files
(obviously), but printing the form value only prints one file. I have been trying a number of ways using FormArray
as well, but had no luck so far.
Any ideas? Many thanks!
First of all, open your terminal and execute the following command on it to install angular app: Then, Open app.module.ts file and import HttpClientModule, FormsModule and ReactiveFormsModule to app.module.ts file like following: In this step, create simple reactive form with input file element and file upload tag.
You can easily file upload with angular 6, angular 7, angular 8, angular 9, angular 10, angular 11, angular 12 and angular 13 application.
Here, we will simple create reactive form using formGroup. input file onchange event we will add file to another formgroup element. then after click on submit button we will call web api for store that file to server.
In the example below there are four steps required to upload files: Select single or multiple files from the input and Set a component variable to the selected files into a FormData object and Populate the FormData object with Files from selected folder files and
Below is example that how I achieved multiple photo upload input file through angular reactive forms.
public demoForm: FormGroup;
constructor(private formBuilder: FormBuilder) {
this.demoForm = this.formBuilder.group({
text_input: ['', Validators.required],
photos: this.formBuilder.array([])
});
}
// We will create multiple form controls inside defined form controls photos.
createItem(data): FormGroup {
return this.formBuilder.group(data);
}
//Help to get all photos controls as form array.
get photos(): FormArray {
return this.demoForm.get('photos') as FormArray;
};
detectFiles(event) {
let files = event.target.files;
if (files) {
for (let file of files) {
let reader = new FileReader();
reader.onload = (e: any) => {
this.photos.push(this.createItem({
file,
url: e.target.result //Base64 string for preview image
}));
}
reader.readAsDataURL(file);
}
}
}
In component html
<input type="file" class="custom-file-input form-control" id="files" multiple (change)="detectFiles($event)" accept="image/x-png,image/jpeg">
<div class="images-preview mt-2" *ngIf="photos.length">
<div formArrayName="photos" *ngFor="let photo of photos.controls; let i = index;">
<div [formGroupName]="i">
<img [src]="photo.controls.url.value" class="card-img-top" alt="Image Preview">
</div>
</div>
</div>
You can avoid html if you do not want to show preview. On submit of form you will be get values like below.
{
text_input: "",
photos: [
{
file: <File Object>,
url: <Base64 String here>
},
{
file: <File Object>,
url: <Base64 String here>
},
....
]
}
Edit Here is working stackblitz example
I hope it will helps you and also other peoples. Thanks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With