Using reactive form validation with <input type="file"> for an Angular app
Solution 1:
As @ibrahim mention it's not implemented yet, but i got the same problem and solved it using hidden
field. on onFileChange
method set file.name
to hidden
field, where you can validate.
<form class="mt-4" [formGroup]="form">
<div class="form-group form-inline">
<label class="btn btn-secondary btn-file">Browse
<input name="file" type="file" (change)="onFileChange($event)">
<input type="hidden" name="fileHidden" formControlName="imageInput"/> <!-- Validation Field -->
</label>
<p *ngIf="file" class="pl-4 align-middle mb-0">{{file.name}}</p>
</div>
<button type="button" class="btn btn-primary">Upload</button>
</form>
onFileChange($event) {
let file = $event.target.files[0]; // <--- File Object for future use.
this.form.controls['imageInput'].setValue(file ? file.name : ''); // <-- Set Value for Validation
}
fileName = '';
this.form = this.formBuilder.group({
imageInput: [fileName, Validators.required]
});
Solution 2:
export class myClass implements OnInit {
myForm = new FormGroup({
name: new FormControl(''),
myFile: new FormControl('')
})
onFileChange($event) {
this.myForm.patchValue({
myFile: $event.target.files[0]
})
}
}
<input type="file" (change)="onFileChange($event)">
Solution 3:
The value of <input type="file">
is read-only, You need to set the option emitModelToViewChange:false
when calling setValue()
to avoid that error :
ERROR DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.
SOLUTION :
this.form.get('<name>').setValue(file, {emitModelToViewChange: false});