1

I have a save button outside form. on save button click i want to display mat error. But it does not get displayed. I Tried using this.form.markAsDirty() & this.form.markASTouched() but nothing works.

<form [formGroup]="form">
 <div formArrayName="products" *ngFor="let product of form.get('products').controls; let i = index;">
  <div [formGroupName]="i">
    <mat-form-field>
      <input type="text" formControlName="productCode">
      <mat-error>
          Blank Error
      </mat-error>
    </mat-form-field>
    <mat-form-field>
      <input type="text" formControlName="productName">
      <mat-error>
          Blank Error
      </mat-error>
    </mat-form-field>
   </div>
  </div>
<form>
<div>
   <button type="button" (click)="SaveProducts()">Save</button>
</div>

angular code:

addProduct() {
  this.form.get('products').push(this.getProductGroup())
}

SaveProducts() {
  this.form.markAsDirty();
  this.form.markAsTouched();
  if(this.form.valid) {
     //save products
  }
}
4
  • <mat-error *ngIf="form.controls.productCode.errors?.required"> ProductCode is <strong>required</strong> </mat-error> you want show something like that? or You can create custom validator for dirty and touched Commented Dec 9, 2018 at 17:41
  • no, i am not looking for that if else Commented Dec 9, 2018 at 17:49
  • I found the fix. I have to loop through entire formarray and access each FormControl and mark it as touched. Is there a better solution? Commented Dec 9, 2018 at 17:51
  • Have you look at this link maybe its can be help you because some posible condition are there (stackoverflow.com/questions/46745171/…) Commented Dec 9, 2018 at 17:56

1 Answer 1

3

Marking the whole FormGroup as touched is not going to make it's children as touched. That's something that you'll have to do explicitly as Angular is not going to do that implicitly. Read this thread for more info on the rationale behind that.

That being said, you can explicitly call markAsTouched on each FormControl in each FormGroup in the 'products' FormArray.

Here's how:

(<FormArray>this.form.get('products')).controls.forEach((group: FormGroup) => {
  (<any>Object).values(group.controls).forEach((control: FormControl) => { 
      control.markAsTouched();
  }) 
});

Here's a Working Sample StackBlitz for your ref.


PS: I've made some more modifications to the mat-errors so that they show up only when the FormFields are touched and are invalid. Also, an ideal user experience would be to disable the Save button in the first place. And show the user an error when they touch the fields. Also, marking the field labels as required(*) can be considered as a good UX.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.