Form validation with ControlValueAccessor

Share on facebook
Share on google
Share on twitter
Share on linkedin

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,  registerOnTouchedregisterOnChange 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.

Related Posts and Comments

Using the Adapter Pattern in Angular Apps for Easier Maintenance

This post is based on something I learned that completely changed the way I designed Angular applications. Core UI components in the app such as buttons can change a lot, which can be a pain to maintain if you have to fix this in a lot of places. One example is using Angular Material buttons and

Read More »

Angular custom validators + trick for flexible custom validator

One of the biggest strengths of Angular is its’ forms library for handling forms logic. Even though Angular has some built-in form validators as required, it sometimes is necessary to create your own form validators. Template driven and reactive forms In Angular, there are two form modules: template driven and reactive. The template-driven allows you

Read More »

Dynamic Form Rendering with Angular Reactive Forms

A common need in enterprise application development is to support dynamically rendering of a form based on some domain-specific metadata. This enables central control of domain logic and enables non-technical domain expert to control central domain logic that determines how the application is rendered, commonly using some CMS like GUI, presented in the domain language

Read More »