I have a form using angular 7. I'm having an issue with my FormGroup, and HTML inputs associated with that FormGroup's FormControls falling out of sync after resetting. My inputs are cleared, but my form controls have the expected reset values.
I can get them to stay in sync by using a reset button that is not of type "reset" but binds its onclick event. Also, I can get the semantically correct reset button to work by swallowing the event and proceeding with form reset.
However, this feels semantically incorrect to me. Not to mention, the production version of the code I want to use works much more conveniently with the semantically correct code, provided I can get this synchronization issue sorted out.
For reasons of simplicity and behavior isolation, I have adapted code from angular's docs https://angular.io/api/forms/FormControlName
Below is my problematic code
import {Component} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
@Component({
selector: 'example-app',
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit()" (reset)="resetToDefault()">
<div *ngIf="first.invalid"> Name is too short.</div>
<input formControlName="first" placeholder="First name">
<input formControlName="last" placeholder="Last name">
<button type="submit">Submit</button>
<button type="reset">Reset</button>
</form>
`,
})
export class SimpleFormGroupComponent {
form = new FormGroup({
first: new FormControl('Nancy', Validators.minLength(2)),
last: new FormControl('Drew'),
});
get first(): any {
return this.form.get('first');
}
onSubmit(): void {
console.log(this.form.value); // {first: 'Nancy', last: 'Drew'}
}
resetToDefault(): void {
this.form.reset({first: 'wicca', last: 'woo'});
}
}
Below is my code that behaves as desired
import {Component} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
@Component({
selector: 'example-app',
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div *ngIf="first.invalid"> Name is too short.</div>
<input formControlName="first" placeholder="First name">
<input formControlName="last" placeholder="Last name">
<button type="submit">Submit</button>
<!--Changed from type="reset" button to button with click event binding-->
<button (click)="resetToDefault()">Reset</button>
</form>
`,
})
export class SimpleFormGroupComponent {
form = new FormGroup({
first: new FormControl('Nancy', Validators.minLength(2)),
last: new FormControl('Drew'),
});
get first(): any {
return this.form.get('first');
}
onSubmit(): void {
console.log(this.form.value); // {first: 'Nancy', last: 'Drew'}
}
resetToDefault(): void {
this.form.reset({first: 'wicca', last: 'woo'});
}
}
Here is another iteration that works correctly, it catches the event and stops it, before proceeding with my reset code.
import {Component} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
@Component({
selector: 'example-app',
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit()" (reset)="resetToDefault($event)">
<div *ngIf="first.invalid"> Name is too short.</div>
<input formControlName="first" placeholder="First name">
<input formControlName="last" placeholder="Last name">
<button type="submit">Submit</button>
<button type="reset">Reset</button>
</form>
`,
})
export class SimpleFormGroupComponent {
form = new FormGroup({
first: new FormControl('Nancy', Validators.minLength(2)),
last: new FormControl('Drew'),
});
get first(): any {
return this.form.get('first');
}
onSubmit(): void {
console.log(this.form.value); // {first: 'Nancy', last: 'Drew'}
}
resetToDefault(event): void {
event.preventDefault();
event.stopPropagation();
this.form.reset({first: 'wicca', last: 'woo'});
}
}
Is there a "better" way to perform a form reset with angular's FormGroup than what I have written above?