2

My goal is to reset the form fields and validators. It's currently clearing both after the first form submission. But then you are able to submit again without validation. Please see my stackblitz - Submit the form normally, then leave the form fields empty and click the 'Add' button again. You'll see that the form submits fine without errors. That shouldn't happen. I need the validation working properly EVERY time the 'Add' button is clicked. I've tried various combinations of the following to no avail:

  • .markAsPristine()
  • .markAsUntouched()
  • .clearValidators()
  • using a formGroup
  • using a formGroupDirective

HTML

<table style="width: 300px;">
    <thead>
        <tr>
            <th style="text-align: left;">Name</th>
            <th style="text-align: left;">Value</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let data of customData; let i=index;">
            <td>{{ data.name }}</td>
            <td>{{ data.value }}</td>
            <td style="text-align: right;"><button (click)="remove(i)">X</button></td>
        </tr>
    </tbody>
</table>

<br><br>

<form (ngSubmit)="add()">
    <mat-form-field class="full-width">
        <mat-label>Name</mat-label>
        <input matInput required [formControl]="customDataNameControl" />
        <mat-error *ngIf="customDataNameControl.hasError('required')">Required.</mat-error>
    </mat-form-field>
    <br><br>
    <mat-form-field class="full-width">
        <mat-label>Value</mat-label>
        <input matInput required [formControl]="customDataValueControl" />
        <mat-error *ngIf="customDataValueControl.hasError('required')">Required.</mat-error>
    </mat-form-field>
    <br><br>
    <button type="submit">Add</button>
</form>

TS

import { Component, OnInit } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-item-list',
  templateUrl: './item-list.component.html'
})
export class ItemListComponent implements OnInit {
  customData = [
    { name: 'sample name 1', value: 'sample value 1' },
    { name: 'sample name 2', value: 'sample value 2' },
    { name: 'sample name 3', value: 'sample value 3' }
  ];
  customDataNameControl = new FormControl('', [Validators.required]);
  customDataValueControl = new FormControl('', [Validators.required]);

  constructor() {}

  ngOnInit(): void {}

  // Remove
  remove(index: any) {
    let confirmation = window.confirm('Delete? This cannot be undone!');
    if (confirmation == true) {
      this.customData.splice(index, 1);
    }
  }

  // Add
  add() {
    if (this.customDataNameControl.valid && this.customDataValueControl.valid) {
      let newCD: any = {
        name: this.customDataNameControl.value,
        value: this.customDataValueControl.value
      };
      this.customData.push(newCD);
      this.customDataNameControl.reset();
      this.customDataValueControl.reset();
      this.customDataNameControl.setErrors(null);
      this.customDataValueControl.setErrors(null);
    }
  }
}
dawphin777
  • 43
  • 1
  • 7

2 Answers2

0

You can use the FormGroupDirective resetForm() method. Live example.

meblum
  • 1,654
  • 12
  • 23
  • Thanks but the validation errors persist after submit. My goal is to reset the form fields and validators so the form has the initial behavior and appearance after each submit. – dawphin777 Jun 22 '21 at 14:05
  • Sorry, I misunderstood the question. I updated the answer and the example, please check it out. See also https://stackoverflow.com/questions/48216330/angular-5-formgroup-reset-doesnt-reset-validators – meblum Jun 22 '21 at 19:43
  • Also https://github.com/angular/components/issues/4190 and https://github.com/angular/angular/issues/15741 – meblum Jun 22 '21 at 19:43
  • If you were using a FormGroup couldn't you just do something like this.formgroup.setErrors(null); – Full Time Skeleton Jun 23 '21 at 10:57
  • No, removing the errors will allow you to submit the form with empty fields. You don't want to remove the errors, we just want to mark the form as not submitted so the form field removes the error indicators. – meblum Jun 23 '21 at 13:45
0

I struggled with trying unsuccessfully to reset forms as per the examples and referenced all the older stackoverflow questions related to this.

In my case, all the Material forms stopped work because somewhere in my app, in an unrelated shared module, I handled an asynchronous message from RXJS that triggered an navigation outside of the Angular Zone. I found once this occurs, this will break form validation in Angular Material throughout the app. So, in referencing a solution that solved this form me the closest one is this: Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?

In the console, I had a warning message in the console Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?

I understand that to solve this message I had to wrap a navigation in a zone when processing this Asynchronous message.

this.zone.run(() => {
                    this.router.navigate(['/home']);
                });

Once I was properly handling async messages in the zone, my Angular Material Forms all worked just fine. Go figure.

pbmz
  • 1
  • 1