I'm wrapping a Kendo Editor component in a custom component to make it reuseable and reduce boilerplate code. I have it working for the most part except for when the parent form.reset() is called.
component.ts
import { Component, forwardRef, OnDestroy } from '@angular/core';
import { ControlValueAccessor, FormControl, NG_VALIDATORS, NG_VALUE_ACCESSOR, Validator, Validators } from '@angular/forms';
import { ERROR_MESSAGES } from 'core/constants';
import { noWhitespaceValidator } from 'core/helpers/customValidators';
@Component({
selector: 'test-input',
templateUrl: './test-input.component.html',
styleUrls: ['./test-input.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TestInputComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => TestInputComponent),
multi: true
}
]
})
export class TestInputComponent implements ControlValueAccessor, OnDestroy, Validator {
// Step 3: Instead of a simple string variable, use a FormControl
onChange: any = () => {}
input = new FormControl('', [Validators.required, noWhitespaceValidator]);
// Step 4: use the setValue method on the form control to update it when a new value comes in from the outside
writeValue(input: string) {
this.input.setValue(input);
}
// Step 5: Listen to value changes on the form control. If something happens, the function provided by Angular will be called and the outside world will be informed.
subscriptions = [];
registerOnChange(fn: any): void {
this.subscriptions.push(
this.input.valueChanges.subscribe(fn)
);
}
ngOnDestroy() {
this.subscriptions.forEach(sub => sub.unsubscribe());
}
// Step 6: onTouch stays the same
onTouch: any = () => {}
registerOnTouched(fn: any): void {
this.onTouch = fn;
}
validate(_: FormControl) {
return this.input.valid ? null : this.input.errors;
}
getErrorMessage() {
if (this.input.errors['required']) {
return ERROR_MESSAGES.REQUIRED_WHEN_SENDING_RESOLUTION;
}
if (this.input.errors['whitespace']) {
return ERROR_MESSAGES.WHITESPACE;
}
}
}
component.html
<div>
<kendo-label [text]="label" class="rich-text-label"></kendo-label>
<kendo-editor [formControl]="input" (blur)="onTouch()" >
<kendo-toolbar>
<kendo-toolbar-buttongroup>
<kendo-toolbar-button kendoEditorBoldButton></kendo-toolbar-button>
<kendo-toolbar-button kendoEditorItalicButton></kendo-toolbar-button>
<kendo-toolbar-button kendoEditorUnderlineButton></kendo-toolbar-button>
</kendo-toolbar-buttongroup>
<kendo-toolbar-colorpicker
kendoEditorForeColor
></kendo-toolbar-colorpicker>
<kendo-toolbar-colorpicker
kendoEditorBackColor
></kendo-toolbar-colorpicker>
<kendo-toolbar-buttongroup>
<kendo-toolbar-button
kendoEditorInsertUnorderedListButton
></kendo-toolbar-button>
<kendo-toolbar-button
kendoEditorInsertOrderedListButton
></kendo-toolbar-button>
</kendo-toolbar-buttongroup>
<kendo-toolbar-buttongroup>
<kendo-toolbar-button
kendoEditorCreateLinkButton
></kendo-toolbar-button>
<kendo-toolbar-button kendoEditorUnlinkButton></kendo-toolbar-button>
</kendo-toolbar-buttongroup>
</kendo-toolbar>
</kendo-editor>
<mat-error *ngIf="input.invalid">
{{getErrorMessage() | translate}}
</mat-error>
</div>
When I call form.reset on the parent form the value of the FormControl is reset to null, which is correct. All the validation also reflects that the value is null.
The problem is that the previous value is still displayed on the screen. I have verified that the value is getting set properly in the code.
Is there something I'm missing that will make the display value update properly?