I have a custom input component that wraps around some html so I can reuse it in multiple places. Following a guide I created this:
import { Component, Input, Self, Optional } from '@angular/core';
import { ControlValueAccessor, NgControl } from '@angular/forms';
@Component({
selector: 'app-input',
templateUrl: './input.component.html',
styleUrls: ['./input.component.scss'],
})
export class InputComponent implements ControlValueAccessor {
@Input() disabled: boolean;
@Input() label: string;
@Input() placeholder: string = '';
@Input() type: 'text' | 'number' | 'email' | 'tel' | 'password' = 'text';
@Input() widthClass: string;
@Input() invalid: boolean | undefined;
value: any = '';
constructor(
// Retrieve the dependency only from the local injector,
// not from parent or ancestors.
@Self()
// We want to be able to use the component without a form,
// so we mark the dependency as optional.
@Optional()
private ngControl: NgControl
) {
if (this.ngControl) {
this.ngControl.valueAccessor = this;
}
}
/**
* Write form value to the DOM element (model => view)
*/
public writeValue(value: any): void {
this.value = value;
}
/**
* Write form disabled state to the DOM element (model => view)
*/
public setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
}
/**
* Update form when DOM element value changes (view => model)
*/
public registerOnChange(fn: any): void {
// Store the provided function as an internal method.
this.onChange = fn;
}
/**
* Update form when DOM element is blurred (view => model)
*/
public registerOnTouched(fn: any): void {
// Store the provided function as an internal method.
this.onTouched = fn;
}
public onChange(event: any) {}
public onTouched() {}
}
I then use the component like this:
<form [formGroup]="personalDataForm">
<app-input
[type]="'text'"
[label]="'Name'"
[formControlName]="'name'"
></app-input>
</form>
If I submit the form I call:
this.personalDataForm.reset()
But this resets the form only the first time and on every next try the form keeps the value in the UI even though the data in the form is set to null.
How can I updated the UI as well to show empty form?
Here is a stackblitz link to reproduce the issue:
https://stackblitz.com/edit/angular-ivy-dotfqx?file=src/app/app.component.html
CodePudding user response:
Since you are not updating value property on input changes,It's not resetting. You can fix the issue by setting value to value property on every input change
<input
[type]="type"
[placeholder]="placeholder"
[value]="value"
[disabled]="disabled"
(input)="onChange($any($event.target).value);value = $any($event.target).value"
(blur)="onTouched()"
/>
OR
You can add ngModel directive on input field as suggested by @Octavian Mărculescu
<input
[type]="type"
[placeholder]="placeholder"
[(ngModel)]="value"
[disabled]="disabled"
(input)="onChange($any($event.target).value);value = $any($event.target).value"
(blur)="onTouched()"
/>