In Angular 6, triggering a reset on a reactive form will activate all necessary validators

As a beginner in angular 6, I am currently facing an issue with resetting a form after submitting data.

Although everything seems to be functioning properly, when I reset the form after successfully submitting data to the database, it triggers all the required validators in the form.

Despite trying numerous approaches to resolve this, I have been unsuccessful in finding a solution.

My goal is to reset the form and all validators after each submission, before entering new data into the form fields for another submission.

Snippet from app.component.html:

<form [formGroup]="newMemberForm" (submit)="CreateMember(newMemberForm.value)" novalidate>
....
....
</form>

Snippet from app.component.ts:

            this.newMemberForm = this.formBuilder.group({
                  M_Number: ['', [Validators.required]],
                  F_Number: ['', [Validators.required]],
                  M_Name: ['', [Validators.required, Validators.minLength(4)]],
                  M_Status: ['', [Validators.required]],
                  M_Dob: ['', [Validators.required]],
                  M_Sex: ['', [Validators.required]],

                });

       CreateMember(memberForm) { 
        this.dmlService.CreateNewMember(memberForm).subscribe(data => {
              if (data[0]['RESPONSE'] == 'TRUE') 
         {
         this.newMemberForm.reset();
        }
       });
}

Even after resetting the form, the required validators are triggered. If I remove all the validators within the function above, the validations do not work when entering new form data.

I am seeking assistance in completely resetting all validators and the form after each submission, allowing me to submit the next set of form data smoothly.

If anyone could provide guidance on how to solve this issue, it would be greatly appreciated.

Answer №1

To reset, follow the steps below:

In your HTML file:

<form [formGroup]="newMemberForm" #formDirective="ngForm"  
(submit)="CreateMember(newMemberForm.value,formDirective)" novalidate>

In your TypeScript file:

CreateMember(value, formDirective: FormGroupDirective){
 ...
 formDirective.resetForm();
 this.myForm.reset();
}

It's important to note that Angular Material checks the validity of FormGroupDirective and not FormGroup, therefore resetting FormGroup will not reset FormGroupDirective.

You can find more information about this issue here: https://github.com/angular/material2/issues/9347

Answer №2

Although that solution is great, reactive forms offer a unique feature to achieve the same result.

In reactive forms, you can eliminate validations on specific formGroup/formcontrol by using clearValidators().

this.formGroup.clearValidators() or      
 this.formGroup.controls.controlName.clearValidators()

Following this step, it is important to update the form control with the removed validator.

this.formGroup.controls.controlName.updateValueAndValidity()

I utilized this method to resolve a similar issue, and I hope it proves helpful for you as well.

Answer №3

According to information provided in responses here and here, with additional details available in the official documentation:

The issue arises because FormGroup::reset() fails to clear the submitted state, which subsequently triggers validators that utilize ErrorStateMatchers.
The submitted status is monitored by a FormGroupDirective object. To resolve this, utilize FormGroupDirective::resetForm() to reset the form's states.
When using Angular Material, the default ErrorStateMatcher checks for form.submitted along with control.invalid and control.touched.
To address this, you have two options: either gain access to the directive and call resetForm(), or create a custom ErrorStateMatcher that excludes submission state checking, as demonstrated in the official documentation.

Option 1:

@Component({
  selector: '...',
  templateUrl: '...',
  styleUrls: '...'
})
export class MyCustomComponent {

  @ViewChild(FormGroupDirective) formGroupRef: FormGroupDirective | undefined;  // <<----

  myInputFormControl = new FormControl('', [Validators.required]);
  myFormGroup: FormGroup;

  constructor(private fb: FormBuilder, private myService: MyService) {
    this.myFormGroup = this.fb.group({
      myInput: this.myInputFormControl
    });
  }

  onSubmit(): void {
    if (this.myFormGroup.valid) {
      let myData: MyData = {
        myInput: this.myInputFormControl.value;
      }

      // submit form data to server
      this.myservice.submitData(myData).subscribe({
        next: (response) => {
          console.log('Data submitted successfully! Response: ', response);
          this.formGroupRef?.resetForm();               // <<----
        },
        error: (err) => {
          console.log("Errors while submitting data: ", err);
        }
      });
    }
  }
}
<form [formGroup]="myFormGroup" (submit)="onSubmit()">
  <input matInput type="text" [formControl]="myInputFormControl">
    <mat-error *ngIf="myInputFormControl.hasError('required')">
      Value is required
    </mat-error>
</form>

Option 2, utilizing a custom ErrorStateMatcher:

/** Error displayed when an invalid control is interacted with */
export class MyErrorStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    return !!(control && control.invalid && control.touched);
  }
}

@Component({
  selector: '...',
  templateUrl: '...',
  styleUrls: '...'
})
export class MyCustomComponent {

  myInputFormControl = new FormControl('', [Validators.required]);
  myFormGroup: FormGroup;

  myMatcher = new MyErrorStateMatcher();

  constructor(private fb: FormBuilder, private myService: MyService) {
    this.myFormGroup = this.fb.group({
      myInput: this.myInputFormControl
    });
  }

  onSubmit(): void {
    // submit form data to server
    this.myFormGroup.reset();
  }
}
<form [formGroup]='myFormGroup' (submit)="onSubmit()">
  <input matInput type='text' [formControl]='myInputFormControl' [errorStateMatcher]='myMatcher'>
    <mat-error *ngIf='myInputFormControl.hasError('required')'>
      Value is required
    </mat-error>
</form>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Assign a value to ReplaySubject if it is currently devoid of any

I am facing a challenge with my ReplaySubject in the component after content initialization. Whenever it initializes, it always gets set to "/api/bulletin/getall" value and overrides any value assigned to it before in the onViewChanged function. How can ...

Is it feasible to verify the accuracy of the return type of a generic function in Typescript?

Is there a way to validate the result of JSON.parse for different possible types? In the APIs I'm working on, various Json fields from the database need to have specific structures. I want to check if a certain JsonValue returned from the database is ...

What is the best way to utilize RxJs for streaming HostListener events?

Although I've found plenty of resources on binding Angular HostListeners, I'm curious about using RxJs to stream it instead: @HostListener('document:click', ['$event']) handleClick(event: Event) { // etc } I want to cre ...

Django and Angular combine to create a floral mapping feature that allows users to easily return to their task list

I am looking to arrange the output from the flower library (/api/tasks) into a list of objects. The current response includes multiple objects, but lacks a "list wrapper", making it difficult to iterate over. API: An example of the return is as follows: H ...

A Guide to Iterating Through Arrays of Objects Using TypeScript

Currently, I am engrossed in an Angular project where I am fetching an object containing an array of objects from an API. The object being passed to the API as a parameter through my service is called "reportData". Here is an example of the data retrieve ...

Heroku deployment of Angular application encounters launching issue

Currently, I am facing a challenge with deploying my Angular App to Heroku using Git. The application works perfectly fine when run locally through the Angular CLI at localhost. To serve the static files, I have included a small Node.js server. Despite He ...

Tips for adjusting the dimensions of images in the primeng editor

Currently working on an Angular 8 application that utilizes the prime ng editor. I am looking to set limits for image size and dimensions before uploading via the upload image button, but encountering difficulties in implementing this feature. https://i.s ...

Trouble retrieving child structural directive within parent structural directive

Seeking to connect parent structural directive with child structural directive. This shows my attempt to access the child element @Directive({ selector: '[appChildStruralDirective]' }) export class ChildStruralDirective { constructor(privat ...

Issue with loading React Router custom props array but custom string works fine

I am facing an issue with my ReactTS-App where I pass a prop via Router-Dom-Props to another component. The problem arises when I try to use meal.food along with meal.name, or just meal.food alone - it doesn't work as expected. Uncaught TypeError: mea ...

Using an Angular interface for an HTTP request: The statusText message reads as "Error: Unable to Determine."

I've been working on calling an API as an example in Angular using an interface. The API I'm trying to access is located at https://jsonplaceholder.typicode.com/posts. Unfortunately, I encountered the following error message: ERROR HttpErrorResp ...

Subscribe receives a value before it has been properly assigned

I am having trouble returning a value from the subscribe function in my code. Despite trying various solutions found online, I cannot get the function to wait for the value to be assigned before returning it. getMessage(field): string { this.service.get ...

Guide to configuring a not null property in Typescript Sequelize:

Hello there! I am trying to figure out how to set a not null property using TypeScript Sequelize. I have tried using the @NotNull decorator, but unfortunately it does not seem to be working. The errors I am encountering are as follows: Validation error: W ...

When attempting to send a token from an account to a marketplace in ERC721, the transfer caller must either be the owner

Currently, I am in the process of transferring my NFT to a marketplace pragma solidity ^0.8.7; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import & ...

Parallel Execution Issue with RxJS Observable forkJoin

Struggling to understand why my requests aren't executing concurrently with the following code. As a newcomer to RxJS and observables, I would greatly appreciate any guidance on improving this snippet below. Essentially, I am fetching data from a REST ...

Stop/continue a stopwatch Observable

I'm trying to create a basic stopwatch using angular/rxjs6. I've managed to start the timer, but I'm struggling with pausing and resuming it. source: Observable<number>; subscribe: Subscription; start() { this.source = tim ...

Tips for storing an unmatched result in an array with a Regexp

Is it possible to extract the unmatched results from a Regexp and store them in an array (essentially reversing the match)? The following code partially addresses this issue using the replace method: str = 'Lorem ipsum dolor is amet <a id="2" css ...

Exploring the power of makeStyles in Material UI when combined with TypeScript

I am currently in the process of converting a JavaScript template to Typescript. Here is an example of my accordionStyle.ts file: import { primaryColor, grayColor } from "../../material-dashboard-pro-react"; const accordionStyle = (theme?:an ...

Built-in functionality to easily customize gradients within material-ui themes

If we want to customize the theme in material-ui, we can do so by following these steps. import { createMuiTheme } from '@material-ui/core/styles'; const theme = createMuiTheme({ palette: { primary: { main: '#ff4400' } ...

The Primeng ConfirmDialog does not close when either the Yes, No, or Close(X) buttons are clicked

When using the PrimeNg ConfirmDialog (p-confirmDialog) in a P-table to delete a record, I am experiencing an issue where the confirm dialog does not close after clicking Yes/No/close(X). Below is the method that I am calling when clicking on delete: conf ...

Unable to compile TypeScript files using gulp while targeting ES5

After starting my first Angular2 app, I encountered an issue where I couldn't use gulp to compile for es5. Below is the dependencies file: "dependencies": { "@angular/common": "2.0.0", "@angular/compiler": "2.0.0", "@angular/compiler-cli ...