Search code examples
angularangular-reactive-formsangular-forms

Custom validation does not work in Angular


I have a form builder in Angular with a custom validation but I am not able to get type of the file after I read it in my custom validation.

Here is the stackblitz:

https://stackblitz.com/edit/angular-ivy-atwqqc?file=src%2Fapp%2Fapp.component.ts

TS File

function checkFileType(
  control: AbstractControl
): { [key: string]: any } | null {
  const files: File = control.value;
  const errors: string[] = [];

  if (files) {
    console.log(files);
    if (files.type === "txt") {
      errors.push(`${files[0].name} has an invalid type of unknown\n`);
    }
    console.log(files.type); //This is always null. How can I get file type

    return errors.length >= 1 ? { invalid_type: errors } : null;
  }

  return null;
}


  onSelection($event) {
    const fileReader = new FileReader();
      const file = $event.target.files[0];
      fileReader.readAsDataURL(file);
      fileReader.onload = () => {
        this.reactiveForm.patchValue({
          file: fileReader.result
        });
      };  
  }


Solution

  • The problem is coming from the readAsDataURL(). It is encoding it into a base 64 string, which means it doesn't have a property type to look at. In fact it doesn't have any types to look at because it is a string and not a File. If you remove this, and set your file variable to your form, you get the properties you want

    function checkFileType(
      control: AbstractControl
    ): { [key: string]: any } | null {
      const file: File = control.value;
      const errors: string[] = [];
    
      if (file) {
        console.log(file);
        if (file.type === "txt") {
          errors.push(`${file.name} has an invalid type of unknown\n`);
        }
        console.log(file.type); //This is always null. How can I get file type
    
        return errors.length >= 1 ? { invalid_type: errors } : null;
      }
    
      return null;
    }
    
    
      onSelection($event) {
        const fileReader = new FileReader();
          const file = $event.target.files[0];
          fileReader.onload = () => {
            this.reactiveForm.patchValue({
              file: file
            });
          };  
      }