How to validate file like file size and file type before it upload to the server. And how to use this validation with reactive form or template driven approach.
-
your question too broad. – Sudarshana Dayananda Dec 11 '19 at 16:12
-
Take a look: https://netbasal.com/how-to-implement-file-uploading-in-angular-reactive-forms-89a3fffa1a03 – Diego Victor de Jesus Dec 11 '19 at 16:32
4 Answers
By default, reactive or template driven forms do not support files, so you need to create a custom ControlValueAccessor which wraps the File variable. That's exactly what is done here.
Here is the relevant part:
@Component({
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: FileUploadComponent,
multi: true
}
]
})
export class FileUploadComponent implements ControlValueAccessor {
@Input() progress;
onChange: Function;
private file: File | null = null;
@HostListener('change', ['$event.target.files']) emitFiles( event: FileList ) {
const file = event && event.item(0);
this.onChange(file);
this.file = file;
}
constructor( private host: ElementRef<HTMLInputElement> ) {
}
writeValue( value: null ) {
// clear file input
this.host.nativeElement.value = '';
this.file = null;
}
registerOnChange( fn: Function ) {
this.onChange = fn;
}
registerOnTouched( fn: Function ) {
}
}
If you need any validation then you could implement it inside this custom component. Just grab a reference of the NgControl by injecting it and call setErrors accordingly.

- 2,575
- 2
- 19
- 30
I'm not sure if my answer is still relevant. but after some digging and messing around I came up with this solution (taken from my own project). Please keep in mind that I'm using multiple files upload.
HTML:
<input type="file" multiple (change)="onFilePicked($event.target.files)" />
Component: Assuming you are using and have created a formbuilder
this.formBuilder= this.fb.group({
files: ['', [checkFileType]],
//other fields
})
//custom validation
function checkFileType(control: AbstractControl): { [key: string]: any } | null {
const files: File[] = control.value;
let errors: string[] = [];
if (files.length >= 1 ) {
for (let index = 0; index < files.length; index++) {
//Use a type list here to check for your types for example "image/jpeg"
if (files[index].type === '') {
errors.push(`${files[index].name} has an invalid type of unknown\n`);
}
}
return errors.length >= 1 ? { invalid_type: errors } : null;
}
return null; // no file, can be capture by "Required" validation
}
To catch the error in your HTML:
<div *ngIf="files.errors">
<div class="text-danger" *ngFor="let typeError of files.errors.invalid_type">
<span>- {{ typeError }}.</span>
</div>
</div>
This solution did it for me. I hope it helps you as well.

- 21
- 1
- 2
You can get the change event and check for the file size and type
In your ts file have this method.
readFile(fileEvent: HTMLInputEvent) {
const file: File = fileEvent.target.files[0];
console.log('size', file.size);
console.log('type', file.type);
}
And in your html handle onchange event
<input (change)="readFile($event)" type="file" />

- 572
- 3
- 11
The problem is pretty much solvable with HTML itself. No angular related stuff needed.
<form action="/action_page.php">
<input type="file" name="pic" accept="image/*">
<input type="submit">
</form>
The accept property can be used as follows:
<input accept="file_extension|audio/*|video/*|image/*|media_type">
The accept parameters are explained as follows:
- file_extension Specify the file extension(s) (e.g: .gif, .jpg, .png, .doc) the user can pick from
- audio/* The user can pick all sound files
- video/* The user can pick all video files
- image/* The user can pick all image files
- media_type A valid media type, with no parameters. Look at IANA Media Types for a complete list of standard media types
Hope this helps :)

- 584
- 1
- 6
- 21
-
OP clearly stated that he wants to use a reactive or template driven approach – Diego Victor de Jesus Dec 11 '19 at 16:24
-
In case, [this](https://stackoverflow.com/questions/18299806/how-to-check-file-mime-type-with-javascript-before-upload) answer would suffice. – Himanshu Mittal Dec 11 '19 at 16:31