Advanced reusable custom Angular validator

Modern usability concepts require advanced validation technics

David Ibl
4 min readMar 4, 2018

Validators and the valid state of a form are often used to implement user guidance through any kind of workflow. In modern usability concepts, user guidance has to follow rules which increase the complexity of validation concepts.

The following tutorial shows up a way to implement advanced custom validators to fulfil requirements of such concepts.

Rules to respect to implement conclusive user guidance:

  • Every error message should be self-explaining and comprehensive
  • Validation errors should only show up after the user had the chance to enter valid values. At least as late as possible.
  • The valid state of the current context should control the availability of further steps of the process
  • The use of validators within templates should reduce code duplication
  • Validators can be combined with complex validation scenarios

What’s the goal?

Finally, we meet all requirements by implementing validation with three states.

validation with three states

Required validation states:

  • Invalid and untouched -> errors are hidden
  • Invalid and touched -> errors are visible
  • Valid

Modern usability concepts require advanced validation technics

In the shown example two validators are bound to the input. A required validator and a mail validator. Only one error is shown at a time. The form remains invalid until all validators are valid.

One requirement to any validator has been to show a comprehensive message matching the concrete requirement. The required validator should never show a message like “value required”, it should show a message like “Please enter a valid email”.

To separate the responsibilities of every validator and improve the possibility of reusing them, every validator should really validate what it is meant for.

The implementation

First of all, let’s have a look at the required validator.

custom required validator

Mostly that’s the common custom validator implementation for Angular validators. If the value provided is not falsy an object is returned, otherwise null is returned to signal valid state.

Only the object returned to signal invalid state is customized. By convention, it’s defined that every validation result contains at least a message and an order.

The message is a default message or a provided message from the Input parameter. In this way, the validation message can be provided as an attribute on the component getting validated.

The order is used to sort validation messages to only show the most important message at a time. Mostly validators can be put in an order from inaccurate validation to more concrete validation. The order property is used to sort overlapping validation logic.

Now let’s see the email validator.

custom email validator

What’s important here?

First of all, the email validator is valid if no value is set. This means that the email validator itself is not requiring any email at all. The main advantage is that the email validator can be used, even if the corresponding field is an optional value.

The responsibilities of each validator are clearly separated. The possibility to reuse is increased by doing that.

To provide an even better implementation experience we even could implement some kind of token substitution, to enrich validation messages.

replacing tokens within a string

In this way, we could provide valid templates or configuration options of a validator to get used in any custom message. Maybe, to implement a comprehensive message for a date picker. The date pattern could also be provided from some kind of language-aware service. Or maybe we want to provide the required length of a min-length validator.

enrich validation messages with configuration options

Finally, let’s face the implementation of the validators and validation messages.

implementation of custom validators

Don’t stumble about the sort pipe… That’s a custom pipe to sort objects by any property in a given way. The my-input-form component is a custom angular component extending ControlContainer and implementing ControlValueAccessor. More on that maybe another time.

The invisible flag within a validation result can be used to get an invalid form without showing up any message any time.

The properties pipe is important up here. The framework itself is providing an object containing all validation errors as fields. This pipe is reducing the given validation object to an array of objects containing the validation information with a defined API. After this transformation, it is possible to iterate over each validation result and display a list of them.

properties pipe to access all object properties from a field of an object

By listening to the touched state of the control, we can hide validation messages until the control is touched by the user at least one time.

The concrete messages for any validation scenario are annotated directly on the validated component by an attribute (requiredMessage). In this way, a comprehensive message can be defined depending on the concrete usage scenario of the control.

Finally, it would be possible to implement a custom component showing validation messages in the same way in any scenario. The div containing the validation messages in this example can easily be transferred to a separate component because the logic to display messages will remain the same. Every validation error is containing all the needed information to be displayed.

The result would look like that:

optimized

The last step would be to integrate the component, rendering validation errors, with the control itself.

But that’s stuff for the next tutorial.

Be sure to have a look at my git for other examples.

Find a tutorial on how to implement a validator for complex business objects here:

--

--

David Ibl

Chief Platform Officer @lv1871 the fanciest assurance company