Angular custom validator not firing when input untouched?

3.7k Views Asked by At

I have a reactive form as following:

this.form = this.formBuilder.group({
  name: ['', Validators.required],
  email: ['', this.customValidator()]
});

I also have a "submit" button with a [disabled] condition:

<button [disabled]="form.invalid" (click)="create()">Create</button>

If email input is untouched and I modify name input, customValidator is not fired and Create button enables despite the customValidator() would return an error.

On the other hand, the name control has a Validators.required validation that is fired even if the input is untouched, which is the desired behaviour.

Example on stackblitz: I want the email input to be required (and the create button to be disabled) when name has value on it even if email is untouched.

4

There are 4 best solutions below

3
On BEST ANSWER

Please check this solution. Instead of abstratcontrol I've used FormControl which is much easier to handle. Also you can pass the parent-child param to the custom validator as seen on this example:

 ngOnInit() {
    this.form = this.formBuilder.group({
      name: ['', Validators.required],
      email: ['', this.customVal('name')], -> you can pass the value here
    });
  }

Please check the stackblitz for complete solution.

https://stackblitz.com/edit/angular-custom-validator-uhhicz?file=src/app/app.component.ts

1
On

Can you try this :

  ngOnInit() {
    this.form = this.formBuilder.group({
      name: ['', Validators.required],
      email: ['', [Validators.required, this.customVal()]],
    });
  }
1
On

Found a couple ways for solving the problem:

1 Angular cross-validation.

The custom validator is applied to the FormGroup and not to the FormControl. The validation is executed every time the form is modified.

this.form = this.formBuilder.group({
  name: ['', Validators.required],
  email: ['']
}, { validators: this.customValidator});

2 Subscribe to form valueChanges + updateValueAndValidity.

this.form = this.formBuilder.group({
  name: ['', Validators.required],
  email: ['', this.customValidator()]
});

And on ngOnInit, whenever the form changes, the validation is executed:

this.form.valueChanges.subscribe(x => {
    this.form.get('email').updateValueAndValidity();
})
0
On

As Iñigo say, a FormControl only is "validate" if is modify the input or if you call manually to "updateValueAndValidity".

So another way is subscribe to form.get('name').valueChange (not forget unsubscribe)

this.form.get('name').valueChange.subscribe(_=>{
  this.form.get('email').updateValueAndValidity()
})

Or we can use input event in .html

<input formControlName="name" class="form-control" placeholder="Name" 
      (input)="form.get('email').updateValueAndValidity()" />