Saturday, April 8, 2023

Angular Reactive Form - File validators for File Upload

File upload fuctionality is a very common use case in applications. Whenever we allow users to upload files to server, we should have both client side and server side validation. Most likely we validates file size and file extension.
In this post, we are going to see the validators for File Upload functionality in Aangular Reactive Form.

file-validations.ts

In file-validations.ts, we have three validators- FileExtension validator, FileMaxSize validator and FIle Minimum size validator.
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
const FILE_MAX_SIZE = 2048;
const FILE_MIN_SIZE = 1024;
export class FileValidations {
  public static fileExtensionValidator(
    acceptedExtensions: string[]
  ): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (control.value) {
        const ext = control.value.split('.').pop();
        if (!acceptedExtensions.includes(ext)) {
          return {
            fileExtension: {
              acceptedExtensions: acceptedExtensions,
              actualExtension: ext,
            },
          };
        }
      }
      return null;
    };
  }
  public static fileMaxSizeValidator(files: FileList): ValidatorFn {
    return (): ValidationErrors | null => {
      if (files.length > 0) {
        if (Math.round(files[0].size / 1024) > FILE_MAX_SIZE) {
          return {
            fileMaxSize: {
              requiredSize: `${Math.round(FILE_MAX_SIZE) / 1024}MB`,
              actualSize: `${Math.round(
                Math.round(files[0].size / 1024) / 1024
              )}MB`,
            },
          };
        }
      }
      return null;
    };
  }
  public static fileMinSizeValidator(files: FileList): ValidatorFn {
    return (): ValidationErrors | null => {
      if (files.length > 0) {
        if (Math.round(files[0].size / 1024) < FILE_MIN_SIZE) {
          return {
            fileMinSize: {
              requiredSize: `${Math.round(FILE_MIN_SIZE) / 1024}MB`,
              actualSize: `${Math.round(
                Math.round(files[0].size / 1024) / 1024
              )}MB`,
            },
          };
        }
      }
      return null;
    };
  }
}

file-upload.component.ts

export class FileUploadComponent {
  uploadForm: FormGroup;
  acceptedExtensions = ['pdf'];
  constructor(private formBuilder: FormBuilder) {
    this.uploadForm = this.formBuilder.group({
      fileToUpload: [
        '',
        [
          Validators.required,
          FileValidations.fileExtensionValidator(this.acceptedExtensions),
        ],
      ],
    });
  }
  public uploadFile(event: any) {
    if (!!event.target.files) {
      this.uploadForm
        .get('fileToUpload')
        ?.addValidators([
          FileValidations.fileMaxSizeValidator(event.target.files),
          FileValidations.fileMinSizeValidator(event.target.files),
        ]);
      this.uploadForm.get('fileToUpload')?.updateValueAndValidity();
      if (this.uploadForm.valid) {
        // To Do : Implement your code here
      }
    }
  }
  get fileToUploadControl(): FormControl {
    return this.uploadForm.get('fileToUpload') as FormControl;
  }
}

file-upload.component.html


Invalid File Extension. Accepted File Extensions-{{acceptedExtensions}}
File size excceds. Maximum allowed file size is 2MB
Minimum allowed file size is 1MB
FileUpload Validation in Angular
You can find the sample code here.

No comments:

Post a Comment

^ Scroll to Top