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

Using default parameters in a versatile function

There is a function called zip with the following signature: function zip<T, U, V>(ts: T[], us: U[], zipper: (t: T, u: U) => V): V[] An attempt is made to assign a default value of (t, u) => [t, u] to the zipper argument: function zip<T, ...

Rendering a component in React based on multiple conditions

Checking sessionStorage and another state variable before rendering a component is essential for my application. I want to avoid showing the same message multiple times within the same session. This is how I have implemented it: const addSession = (noteId: ...

JavaScript Enigma: Instantiate 2 Date variables with identical values, yet they ultimately display distinct dates on the calendar

I need some help understanding something in my screenshot. Although both tmpStart and itemDate have been assigned the same numeric value, they display different calendar dates. start = 1490683782833 -> tmpStart = "Sun Mar 26 2017 16:51:55 GMT+ ...

Using parameters to create unions in TypeScript

Is there a standard method to parametrically define a union? I'm searching for a way to generically define something like: type U<K> = T<K1> | T<K2> | ... | T<Kn> // Where K === (K1 | ... | Kn) Note: I'm encountering a s ...

Access to the server has been restricted due to CORS policy blocking: No 'Access-Control-Allow-Origin'

I’m currently encountering an issue with displaying API content in Angular and I’m at a loss on how to troubleshoot it and move forward. At this moment, my main objective is to simply view the URL data on my interface. Does anyone have any insights or ...

Setting up a Variable with an Object Attribute in Angular

I am attempting to create a variable that will set a specific property of an object retrieved through the get method. While using console.log in the subscribe function, I am able to retrieve the entire array value. However, as a beginner, I am struggling ...

Utilizing various filters and sorting options on API response within Angular 8

Upon receiving the following API response: [ { "imgPaths":[ "gallery/products/55ccb60cddb4d9bded02accb26827ce4" ], "_id":"5f3e961d65c6d591ba04f3d3", "productName":" ...

Utilizing Rxjs' distinct operator to perform deep object comparisons with nested values

Within my observable, I am receiving a JSON object and using the distinct operator to avoid duplicates. The challenge is that I want to prevent duplicates only if the entire object remains the same as before. Since comparing based on a single attribute suc ...

TypeScript types for d3 version 4

I am currently working on a d3 project and to simplify the development process and reduce errors, I decided to implement TypeScript. Using d3 v4, I initially faced issues with incorrect type definitions which led to errors like d3 not having a definition ...

ion-grid featuring alternate columns

As someone who is not very familiar with Angular, I am trying to create a grid layout like the one shown here: https://i.stack.imgur.com/nBavk.png The desired layout includes alternating rows with one image followed by two images. My current attempt at a ...

The error `TypeError: Unable to access properties of an undefined value (reading 'authService')` occurred

I'm attempting to check if a user is already stored in local storage before fetching it from the database: async getQuestion(id: string): Promise<Question> { let res: Question await this.db.collection("questions").doc(i ...

To properly display a URL on a webpage using Angular, it is necessary to decode

After my console.log in Angular 5 service call to the component, I can see the correct data URL being displayed http://localhost:4200/inquiry?UserID=645 However, when it is inside an Angular for loop in the HTML template, it displays http://localhost:42 ...

Can one inherit under specific conditions?

I have just started exploring the OOP paradigm and I am curious to know if it is possible to have conditional inheritance in TypeScript. This would help avoid repeating code. Here is what I have in mind. Any suggestions or recommendations are greatly appre ...

What is the procedure for invoking a function when the edit icon is clicked in an Angular application

My current Angular version: Angular CLI: 9.0.0-rc.7 I am currently using ag-grid in my project and I encountered an issue when trying to edit a record. I have a function assigned to the edit icon, but it is giving me an error. Error message: Uncaught Re ...

Using custom properties from the Material-UI theme object with custom props in Emotion styled components: a step-by-step guide

I have implemented a custom object called fTokens into the MUI theme using Module augmentation in TypeScript This is how my theme.d.ts file is structured declare module "@mui/material/styles" { interface FPalette { ... } interface FTokens ...

The path referenced in typings is incorrect

I am currently facing an issue with my Typescript library that I am trying to publish on npmjs. It seems like the types file is not being exported correctly. The library has a simple method in the src/index.ts file and typings from src/typings/index.d.ts. ...

Bug in auto compilation in Typescript within the Visual Studios 2015

Currently, I am utilizing Visual Studio Pro 2015 with auto compile enabled on save feature. The issue arises in the compiled js file when an error occurs within the typescript __extends function. Specifically, it states 'Cannot read property prototyp ...

What is the Reason FormControl#valueChanges Subscriptions are Not Cleaned up by Garbage Collection?

After reading numerous discussions, I've learned that it's important to unsubscribe from `FormControl#valueChanges` in order to avoid memory leaks. I now understand the importance of knowing when and how to unsubscribe from Observables, especiall ...

Mastering Angular2: Leveraging TypeScript's Power to Unleash JavaScript ES6 Syntax with

I am having trouble implementing a translation feature using the ng2-translate pipe in my Angular2/Ionic2 app, which is entirely written in JavaScript ES6. However, I have encountered an issue during the setup phase. The code snippets I have found on the ...

Iterating through an array and setting variables according to asynchronous code

I have created a function to loop through an array, call a promise, and update a variable based on the result. The code seems to be functioning correctly, but I am wondering if there is a more optimal way to write it. Any suggestions are appreciated. Tha ...