I'm writing a component with a file picker that uploads a file to our CDN. I'm trying to add a reactive form on this component to validate the image input, so I can check against file name/extension etc, and keep it wrapped it in a form so I can keep the benefits of Angulars validation.
My component HTML is
<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)="onChange($event)" formControlName="imageInput"
</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>
And my component code behind is
onChange(event: EventTarget) {
// file picker code
this.form = this.formBuilder.group({
imageInput: [this.file.name, CustomValidators.imageValidator]
});
}
The CustomValidars.imageValidator
only just logs the input at the minute.
When the component is loaded, the error message displays as 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.
Basically, I want to use the file input in my reactive form, so I can validate against the filename.
get("FileUpload") . setValidators([ Validators. required, FileValidator. validate, fileSizeValidator(event), requiredFileType(["jpg", "png", "txt"]) ]);
When using Reactive Forms in Angular, you define custom validators with functions. If the validator does not need to be reused, it can exist as a function in a component file directly. Otherwise, if the validator needs to be reused in other components, it can exist in a separate file.
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]
});
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)">
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});
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