简体   繁体   中英

File validation in angular 7

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.

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.

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" />

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.

example output (greetings from Belgium :D) 在此处输入图片说明

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) (eg: .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 :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM