What we see here is an HTML form that uses the reactive kind of style for creating forms in Angular. As you can see in our personAdded component class, we created such a form group, which here in the constructor, we invoke the createForm method.
That createForm method basically creates such a form group by using the the form builder. You can also here immediately see that we define a firstName property of our form module, which has an empty value initially, and also specifies a required validator. This is one of the built-in validators for Angular forms.
If we scroll up, we see in the template here, we bind to our form group, which we have defined below here. We define our input field for the firstName, and just below the input field, we basically have this div block here that is responsible for displaying our validation errors.
In fact, you can see we activate it whenever the firstName model here gets invalid, and whenever someone actually modifies it or touches it. Then for below here, we then display the single kind of error. In this case, for instance, the required validator.
What we would like to do now is to create our customer validator. Let's call it name.validator. A customer validator in Angular reactive forms is nothing else than a function -- let's call it nameValidator -- which returns a validator function.
This is somehow the constructor function for the actual validation function gets invoked by the form. This is a function that gets a control which of type abstractControl. As you can see, we import all of them here from Angular forms.
That abstractControl, again, returns a set of validation errors or null based on whether the output is valid or not. Inside here, we can then do the validation. isValid equals the control.value, whenever that is basically empty, or the control.value matches a given name.
That name is something we basically specify here as a parameter, which we then pass in from the outside. Great, so whenever the control is valid, we basically return null. In your scenario, we return an object that can then be used by the user of our validator to display the error message.
We call this nameMatch, and here we basically return the allowedName property, which the user could then visualize in the errorMessage property. Once we have specified that name validator, we can directly jump back to our component.
We can import it there, and then we scroll down where we define our form, and we can then hook it up directly inside here. Basically, we wrap this one again as an array. Here, we then can directly reference our name validator.
We say static value, Yuri, for instance. In order that the error also gets displayed properly, let's also copy here the displaying of the error message. Here, basically we access the firstName again, the errors, but now the nameMatch field, which we have specified. Basically, this one here.
We can then provide a proper error message. Here we then access directly to that allowedName property, which we pass along whenever the validator basically fails, so form.get(firstName). Now, if you type something in here, you can see that we get the proper error message, "You have to provide a valid name, such as Yuri."
Whenever we write Yuri, basically the form validates properly. Obviously, that name which we specify in here can be a variable. We could pass in here simply a value which defined on the fly by our person component.