14

ngControl with a value of new Control('', Validators.required) didn't work even when the file is valid.

(and actually, I found it difficult to validate radio buttons as well...)

chitakuma
  • 329
  • 4
  • 11
  • 1
    self-solved. **html** `` **ts** `controlName.updateValue(value)` (value is set via FileReader) – chitakuma Jan 22 '16 at 12:39
  • hey @Yusu can you answer you own question and provide all relevant code which worked for you...?? – hhsadiq Mar 23 '16 at 08:54
  • @YuSu Can you indeed please provide all relevant code, cause I'm not able to do it as you tell. If I try with `this.frm.patchValue({ file: evt.target.value });` I'm getting: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string. – S. Robijns Jan 26 '17 at 15:17
  • Check my answer [here](https://stackoverflow.com/a/41938495/5413117) for a full working example + explanation – S. Robijns Aug 17 '17 at 10:58

3 Answers3

5

Validators.required depends on the value of the field.

Input type file does not have a value, therefore is considered as undefined or null.

That is why it is invalid. Better write you own validation.

For custom file validation example refer

mayur
  • 3,558
  • 23
  • 37
1

An example of validator to use with the normal require attribute could be something like this

import { Provider, forwardRef, Directive } from '@angular/core';
import { NG_VALIDATORS, Validator, Control } from '@angular/common';
export const NO_ATTACHMENT_VALIDATOR = new Provider(NG_VALIDATORS,{
  useExisting: forwardRef(() => noAttachmentValidator ),
  multi: true
});

@Directive({
  selector: '[noAttachmentValidator][ngControl],[noAttachmentValidator][ngFormControl],[noAttachmentValidator][ngModel]',
  providers: [NO_ATTACHMENT_VALIDATOR]
})

export class noAttachmentValidator implements Validator{
  public validate(control: Control) : { required: { [key: string]: boolean } | null } {
    let state,
        value = control.value,
        alreadyUsed = control.dirty;

    if(alreadyUsed && value.length == 0){
      state = true;
    }
    return state ? { required : { 'required' : false } } : null
  }
}

Basically required attribute is checking the first time, this every time after that you have used the input the first time,even if you remove the file (that was my problem ) cause the control of the value is for null. And when it's untouched it's null,then it's become filled when you add a file, but if you remove it it's just an empty array so [] !== null . I hope this helps follow this you can build you own type of validation if you need to.

Valex
  • 1,149
  • 1
  • 8
  • 14
0

One great solution to resolve this issue is to create a custom element which wrap your and implements a ValueAccessor. This way you can create a custom component which works exactly like the other form's elements. Instead of using the input value you can use another variable inside your component.

More information here : Applying angular2 form directives to custom input form elements

Community
  • 1
  • 1
Nicolas Forney
  • 868
  • 2
  • 13
  • 21