0

I've got a reactive form with nested formgroups with some form controls that have required validators.

It seems the validation only occurs when a user inputs values into the form. If the form is submitted with no user interaction, empty textboxes with a required validator show as valid. Is this a normal behavior of angular forms? Am I missing something?

Thanks

Pete

html template:

<form [formGroup]="ticketMarkForm" (ngSubmit)="submitTicket()">
  ..
   <div formGroupName ="systemForm">
     <mat-form-field appearance="outline">
      <mat-label>Pipe Length (Ft):</mat-label>
      <input matInput type="number" required formControlName="pipeLength">
     </mat-form-field>
</div>
 ..
 <button type="submit" mat-stroked-button>Submit</button>
</form>

component typescript:

export class MtMarkFormComponent implements OnInit {
..
ticketMarkForm: FormGroup;
...
constructor(private checkService: MTMarkFormCheckService) { }
 ngOnInit(): void {
 //forms
 this.ticketMarkForm = new FormGroup({
  systemForm: new FormGroup({
    ...
   pipeDiameter: new FormControl(Validators.required),
   ...
  })
  });

}
submitTicket() {
   let pipeDiam:any=this.ticketMarkForm.get('systemForm').get('pipeDiameter');
   this.checkService.CheckRequiredValid(pipeDiam);
   }
}

Service to check form typescript:

export class MTMarkFormCheckService {
 CheckRequiredValid(fc: FormControl) {
        if (fc.invalid) {//if the control is left blank/untouched evaluates to valid.  I've also 
  tried to mark the control as dirty (fc.markAsDirty()) but same result
            alert("invalid");
         }
         else {
           alert("valid");
        }
 }
pvitt
  • 1,005
  • 4
  • 14
  • 31

2 Answers2

1

It is default Angular behavior. You have to define custom error state matcher like this.

import {FormControl, FormGroupDirective, NgForm} from '@angular/forms';
import {ErrorStateMatcher} from '@angular/material/core';

export class CustomErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null | undefined, form: FormGroupDirective | NgForm | null): boolean {
    if (control == null) {
      return false;
    }
    return control.invalid;
  }
}

ts :

export class MtMarkFormComponent implements OnInit {
   :
  public esm = new CustomErrorStateMatcher();
   :
}

html :

<input matInput type="number" required formControlName="pipeLength" [errorStateMatcher]="esm">
Jago
  • 2,751
  • 4
  • 27
  • 41
N.F.
  • 3,844
  • 3
  • 22
  • 53
  • Thanks N.F. I was able to apply your solution but I'm still getting the same behavior. The user has to actually make a change to the value in the control and leave it blank to get an invalid flag for the control – pvitt Mar 23 '21 at 14:57
  • Your Custom Error Matcher was the solution. My problem was when I initialized the control. I used: pipeDiameter: new FormControl(Validators.required) should of used: pipeDiameter: new FormControl('', [Validators.required]). I passed the validator as the first argument. A working stackblitz is here: https://stackblitz.com/edit/angular-ewa1kj?devtoolsheight=33&file=app/input-error-state-matcher-example.ts – pvitt Mar 23 '21 at 16:50
  • the stackblitz above is based on this https://stackblitz.com/angular/brleoyyorkap?file=app%2Finput-error-state-matcher-example.html – pvitt Mar 23 '21 at 16:59
1

This statement is not very clear but will try to explore

empty textboxes with a required validator show as valid

I have tried to replicate the problem you have described in this Stackblitz demo but I am getting different conclusions.

Empty textboxes with required validators will be return false for the valid property

It is important to note that validations on the form will not show until the form is touched

In the demo I have commented out the line // this.ticketMarkForm.markAllAsTouched(). If this is uncommented, validations will show on the form

By default angular will call (ngSubmit)='someFunction()' (see Angularjs prevent form submission when input validation fails) but the form status will be invalid.

If you try to submit the form in the demo You will notice that the console log shows false

Owen Kelvin
  • 14,054
  • 10
  • 41
  • 74
  • Thanks Owen - I can see the form is always invalid no matter the input. I'm going to try and build a stackblitz without the material form input and see what happens – pvitt Mar 23 '21 at 15:21