If we have UI components, that are using inputs, we normally want to hook it into the form handling so we can do form validation and show error messages. This post will show you how to use ControlValueAccessor
to integrate your UI components into the form validation and how to control the error state in an Angular material input using ErrorStateMatcher
.
This is part of the form training in Angular Architect Accelerator. If you want to accelerate your road to become a highly in-demand senior Angular developer through an 8-week seminar, I recommend you go check it out here.
Integrating an adapter UI component with forms using ControlValueAccessor
Let’s consider we were creating a date picker component based on Angular Material’s date picker. Let’s look at the internal implementation of the date picker:
Here we are just setting up an Angular material date picker and wrapping it in an MatFormField
and are using MatError
for showing error messages.
We want to support error handling as well as show an error message in case of errors. To support integrating with the host component’s form validation, we will need to implement ControlValueAccessor
:
The date picker is implementing ControlValueAccessor
by creating the methods: writeValue
, registerOnTouched
, registerOnChange
and setDisabledState
. Note here, that we are integrating the component in the form handling by providing it in the NG_VALUE_ACCESSOR
injection token.
The ControlValueAccessor
methods
Let’s go through what each method does and how each of these are implemented.
writeValue
This method is triggered when a value is set on the component either through [ngModel]
(template-driven forms) or formControl.setValue(someVal)
(reactive forms).
When this is triggered, we set the date on the date property.
registerOnTouched
This method is for setting a callback function for marking the control as touched. We save the callback method in a property and call it in the onDateChange
method.
registerOnChange
Like for registerOnTouched, but for triggering value change events. This method is for setting a callback function for triggering a value change event. We save the callback method in a property and call it in the onDateChange
method with the newly changed date.
setDisabledState
This method will be called when the component is set as disabled using [disabled]="true"
in the host component’s template. We can then pass that value to an isDisabled property in our component and use it to disable the internal date picker implementation.
Implementing the custom ErrorStateMatcher
ErrorStateMatcher
is coming from Angular material’s form field and is a way of specifying when the form control should be reflecting an error state like:
This is done by implementing an isErrorState
method.
For flexibility, we are allowing it to be overridden by a hasError
property or will otherwise reflect error state if the form control is invalid and the parent form is submitted.
Showing error messages
For the most flexibility, we are allowing the consumer to specify what error message to show as well or otherwise fall back to a sensible default using the errorMessage
property.
Using the date picker UI adapter
Now, we can use the date picker UI adapter like this:
Conclusion
We looked at how to integrate a date picker component that wraps Angular material date picker and use it in the form validation by implementing the ValueAccessControl
methods. We also saw how to control the error state of the component using ErrorStateMatcher
and showing error messages.
Do you want to become an Angular architect? Check out Angular Architect Accelerator.