Angular 2: Custom validation for file extensions

11,626

I have a solution, maybe not the perfect one, but it works(same thing would be for file size), here it is:

First on the html file I got the form for file upload, and on it each time I upload a file I call a specific function called fileEvent(), The layout file contains:

   <form [formGroup]="photoForm" (submit)="savePhoto()">
          <table>
            <tr>
              <td>Photo</td>
              <td>
                <div class="file-edit">
                  <input type="file" (change)="fileEvent($event)" formControlName="newPhoto" class="form-control" required #newPhoto>
                </div>
              </td>
              <td><p class="warning">{{fileExtensionMessage}}</p></td>
            </tr>
            <br/>
            <tr>
              <td></td>
              <td><button type="submit" [disabled]='fileExtensionError' class="submit-btn">Save</button></td>
            </tr>
          </table>
        </form>

Please note that if fileExtensionError variable is true the submit button is disabled.

The function fileEvent() which checks validation also gives me the filename, file extension and file content is as below:

 fileEvent(event) : any {
    //*-- this function gets content of uploaded file and validation --
     */
    var file = event.target.files[0];
    this.photoName = file.name;

    var allowedExtensions = 
       ["jpg","jpeg","png","JPG","JPEG","JFIF","BMP","SVG"];
    this.fileExtension = this.photoName.split('.').pop();

    if(this.isInArray(allowedExtensions, this.fileExtension)) {
        this.fileExtensionError = false;
        this.fileExtensionMessage = ""
    } else {
        this.fileExtensionMessage = "Only photos allowed!!"
        this.fileExtensionError = true;
    }

    if (file) {
        var reader = new FileReader();
        reader.onloadend = (e: any) => {
            var contents = e.target.result;
            this.photoContent = contents;
        }
        reader.readAsDataURL(file);
    } else {
        alert("Failed to load file");
    }
}

/*- checks if word exists in array -*/
 isInArray(array, word) {
    return array.indexOf(word.toLowerCase()) > -1;
}

Of course I have these variables declared in my class:

photoName: any;
photoContent : any;
fileExtension: any;
fileExtensionError: boolean = false;
fileExtensionMessage: any;
photoForm : FormGroup;

Hope it helps someone :D

Share:
11,626
ashokmi5
Author by

ashokmi5

Updated on June 14, 2022

Comments

  • ashokmi5
    ashokmi5 almost 2 years

    I am new to angular. I want to create a custom validation for checking the file size and extension. I am using FormBuilder for validation and FileReader API for fetching file name and size of the input element field data.

    Problem: We are able to trigger custom validation on change event but could not fetch value of input type field.

    Please suggest how we can implement custom validation for file extensions and size in angular 2.

    HTML:

    <input type="file" [formControl] = "formName.controls['thumbnailImg']" (change)="changeThumbFile($event)">
    

    Component:

    //custom validation
    function validateExt(c: FormControl) {
        let extension = ['png', 'jpeg', 'gif'];
        return extension.indexOf(c.value)? null : { validateExt: { valid: false } }
    }
    
    this.form = this.formBuilder.group({
      'thumbnailImg': ['', validateExt],
    });
    changeThumbFile($event){
        var file: File = $event.target.files[0];
        var fReader: FileReader = new FileReader();
    
        var imgName = file.name;
        this.thumbnailName = imgName;
    
        this.formGp.controls['thumbnailImg'].updateValueAndValidity();
    }