We had dealt with reactive forms in one of the previous lessons,
where we did two exercises dealing with reactive forms,
how we create them,
and then also do some basic form validation on reactive forms.
We'll continue with the theme in this lesson,
because reactive forms as the name implies,
has something to do with reactive programming as you might have expected.
Now, reactive forms also enable you to watch changes in the values of the form elements,
using an observable that Angular makes available called valueChanges.
We'll make use of the valueChanges observable in this exercise,
in order to track changes to the values of
their various form elements and then immediately trigger form validation.
In this exercise we're going to doing most of the form validation in
code rather than in the template itself,
as we did with the reactor form validation in the second exercise of reactive forms.
Going to contact.component.tsfile,
we're going to update the reactive form that we have created here,
by adding a few more Validators for some of these fields.
So, here you see that for the first last name and
the telephone number and email we have added the required Validators.
For the first and the last name,
I'm going to add in a couple of more Validators for
the minimum length and the maximum length.
Now, if you have more than one Validator in your reactive form,
you have to declare them using an array in there.
So, this has to be enclosed inside an array here.
So, you see that I have enclosed the required Validator inside an array.
I'm going to add in a Validators, minLength Validator.
So, for the minimum length I will specify two as the minimum length,
so the firstname should at least contain two characters.
Also the maximum length that I will
add as 25 characters.
So, here you see that now for the first name we have three different Validations,
all enclosed in an array here.
Validators required, Validators minLength,
and Validators maxLength here, 25.
So, I'm going to do the same thing also for my last name.
So, let me copy this whole Validators ray here,
and then replace this one with that set of Validators.
Now in addition, for the telephone number,
as you would recall in the earlier version of the form,
the telephone number was willing to accept even alphabets,
but that is not correct.
Telephone numbers are usually numbers.
So, this is where we will use another Validator
called pattern Validators.
So, the pattern Validator allows us to specify a pattern for
the values entered into that particular form element,
and then check to make sure that the value follows the pattern specified.
So, here the pattern that we will use is that the value
should contain only numbers between zero and nine.
For adding the pattern,
we need to do that in the template file as we will see in a short while.
Similarly, for the email,
I will also have another Validator called as the email Validator.
So, we'll add in the Validators email.
This also means that we need to add in a attribute
called email to the input in our template file.
Now, with these changes my form validation has now become more robust in this exercise.
Now, when the form experiences changes in any of it's form elements,
then the Angular framework provides an observable called as valueChanges observable.
So, I'm going to use the valueChanges observable on my feedback form.
So, the valueChanges observable.
So, the valueChanges observable can now be subscribed to within this particular method.
So when we create the form itself,
we will subscribe to the valueChanges observable here.
Now, when the valueChanges,
so by subscribing to this observable,
within the subscribe I will specify what should be done when the valueChanges.
So, when the valueChanges I would obtain some data here,
from the farm to indicate
which particular form element has experienced the change in the value.
Then, when that happens,
I'm going to trigger a local method that I will implement called onValueChanged,
and then supply that data as a parameter to this method.
Now, inside this onValueChanged method,
I'm going to initiate the form validation,
and then appropriately define the form error messages based upon what
this data object that I obtain here will specify to me.
Also in addition, when I first create the form,
I will call the onValueChanged method without any parameter,
and this would be used to
reset form validation messages.
Now, how do I create the form validation messages?
To do that, I'm going to define my form validation messages completely in code here.
Then through the code,
I will adapt the form validation messages,
and that would be then used to display the error messages in my form template itself.
So to do that, what I'm going to do is to add a few JavaScript objects in here.
One of the JavaScript objects that I'm going to add is named as form errors.
So, this is a simple JavaScript object that
will contain all the errors for the particular form here.
So within the form errors,
I will use four different fields,
first name, last name.
So as you recall,
these correspond to the four form elements on which I am doing the form validation,
telephone number and email.
Now, why do I define this JavaScript object here?
Now, this JavaScript object as you see contains four elements here.
Now, whenever I do the form validation,
recall that I already specified that
I'm going to create a new method called onValueChange.
Inside the onValueChange, the way the code is written is that,
if any error is detected,
a string containing the message corresponding to
that error will be added into this JavaScript object.
So, this way within my code,
I can do the form validation.
Now, in addition to this,
I will now define a few validation messages.
Now, this particular pattern of doing things,
I learned by reading the documentation on form validation in the angular.io website.
So, they have a whole documentation on how to do form validation and a link to which is
available in the additional resources of
this chapter and also the previous chapters on angular forms.
So, there in that particular document they
prescribe this as a way of doing form validation and I found that to be very intuitive.
So, I also adopted the same pattern for doing form validation in code.
So, along with here,
I'm going to define the validation messages for all the possible fields here.
So, for the first name field,
I will define a few validation messages here, so I would say,
"required" and then say,
"first name is required" like this,
I will add in a few validation messages
here and say,
"First name must be
at least 2 characters long" and then I will also add,
"max length" and the corresponding message would be,
"First name cannot be more than 25".
If you have a name which runs into 25 characters,
you must be really cursing your parents for that, believe me,
one of my middle names is a long middle name,
and which I don't use explicitly in my documents.
But, I can understand the pain,
if you have a long name greater than 25 characters.
People from some states in Southern part of India have long names,
my state included, hey,
let's have some fun while we are at it.
Okay, I'm also going to include the same thing for the last name.
So, I'm going to edit this
and specify the same thing as last name.
So, as you see within the code you can specify a set of error messages.
Now, if you add new validation to your forms,
all that you need to do is,
come here and add in the new error message into
this JavaScript object here and your code will work just fine, as such.
So, that's the advantage of using this pattern for designing your validation in code.
Continuing, let me define the validation for telephone number and
the two validation for telephone numbers that would happen is the "required".
So, I'm just going to copy the "required" from there,
and paste it in here,
and I would say,
"Telephone number is required," and the next error message would be for "pattern".
So, the error message says,
"Telephone number must contain only numbers."
So, that's the other message, similarly for email.
So, as you can see the values that I'm using here
are corresponding to the Validator names that I've used,
"mid length", "max length required", "pattern".
So, similarly for email,
you would see "required" and "Email'.
So, I'm just going to copy the "required" over here and say, "Email is required".
The other pattern as you recall is for email and I would say,
"Email not in valid format".
So, typically if your email doesn't contain
an @ sign and characters on both sides of the @ sign,
then that is not a valid email.
This email Validator is already built into the angular reactive forms module.
So, we'll make use of the email Validator here.
So, here we have all the validation messages defined in code.
So, that makes it very easy to extend them for additional fields if you require and also
adding more validation messages for additional Validations
that you might introduce for each of those form fields.
Also, this object form errors helps me to track
all the errors associated with each of the elements in my phone.
So, currently I only check these four elements,
so that's why I only have for that.
Minor correction, the "mid length" should be min,
small 'l' and max length also with a small 'l',
similarly for the last name also.
Now, let's write the code for the on values changed method.
So, I'm going to write the method
here,"ValueChanged" and then this
will take in a parameter, possibly.
That's why I put a data question mark,
meaning that the parameter is optional.
So, the first thing I will check is, "this feedback form",
which means that if the feedback form has not been created then,
and if this method is called,
then you should simply "return" without anything.
Then, I'll define a
constant called "this feedback
form" is just to make it easy to define the the rest of the code,
then I would say, "for
const field in this.form errors".
So, notice that this field will take this.form errors,
the form errors object that we have defined earlier.
So, feel means that I will check all the four.
So, whenever I detect any changes,
the first name, the last name,
tel number and an email.
So, that's why these four will carry the exact same names as we used in the form here,
and so that the code written here will be straightforward to work with.
So, I'm going to now check the form fields.
Then, I would first
make sure that in case I have earlier attached any messages to these form fields,
form errors object there,
then I'm going to clear all of them.
So, that's why if you call this with no parameter,
all the form error fields will be cleared,
and then I would do, "control FormGet".
So, notice that I am using that field itself to do a FormGet so,
I am getting access to that particular form field.
So, notice that earlier we were doing "feedbackform.this.feedbackform.get"firstname."
and so on. So, I've simplified what into this particular constant that we
defined here and then I will say, "If control".
So, which means that if control is not null and "control.dirty".
So, if that particular field is already dirty
and not "control valid".
So, means that for each of the fields,
I am literally checking to see if it is valid,
if it is dirty,
and then if the control is already there.
Then, I'm going to check to see what kind of errors have been added to
this particular control by the form there.
So, in here I will say,
"const messages equal
to this.validation messages field".
Notice how I am picking up
all the validation messages corresponding to that particular field firstname,
lastname, or telnum or email,
and then I will check and see whether I need to add this into the field.
So, how do I do that?
So, we do for const key in control.errors.
So, notice that this control is feedback form.get field and.error,
so I'm checking to see if there are any errors there.
Then, in that case,
I will add this form errors field.
So, for that particular item in the JavaScript object that I've defined here,
I would add messages key
plus and space here.
So, now whatever form error survey
or the corresponding message will be taken and attached in,
and then so my form errors JavaScript object will now contain
all the error messages attached together when
this particular on values changed method rats.
Now, this particular piece of code I have borrowed from
the form validation documentation on angular.iu.
I found that this is very intuitive way of doing form error checking.
So, I thought why not make use of that within our angular reactive forms exercise.
So, adding this code in there.
Now, my application is all ready to do the form validation for my reactive form.
So, now the next step is to go to the contact component.html,
the template file, and then update the template file.
So, going to that template file,
we will now go to the form,
and the in this form now instead of doing all this checks in code,
we can now simplify a lot of the code here in the template file here.
Now, instead of doing all these checks,
what we realize is that the form errors JavaScript object in
my typescript file if there are errors then
the form errors JavaScript object for that particular field,
will have all the error messages attached to it.
If there are no errors,
then those error messages will not be there.
So, that is what I am going to use to check and
see whether I should display the form error or not.
So, for that matter instead of checking all this,
the only thing that I need to check here is formErrors firstname, that's it.
So, very easy to check for errors here.
Similarly, so this whole code now gets simplified here,
and similarly when you check for the message here,
what we're going to do, I'm going to change this whole thing from
required touched to formErrors.firstname.
That's it. If that exists,
then all the error messages corresponding to this will already be in there,
so I just need to do interpolation and
then display formErrors.firstname here,
as simple as that.
Now, you see by doing
all the form error validation and code and doing all the checks and so on in code,
you have already constructed the error messages that we need to display.
All that we do is we take that error message and then put
this into the template here, that's it.
The template code becomes more simplified in this particular case,
and also by doing the form validation using the typescript code,
we have simplified the template here at at the same time we can do
more complicated form validation in our typescript code.
I'm going to go ahead and do the same kind of changes to the remaining fields here,
so for the lastname field,
I'm going to again replace this whole thing with formErrors.lastname.
Now, again do the same thing for the telephone number.
Now, again as you see the structure of the template becomes very,
very uniform in this case.
So, that also is another way of simplifying
the structure of your template continuing to the email field here.
I'm going to do the same change to the email field also.
So, I would say formErrors.email
and replace this by formatters.email.
So as you can see,
your template code has simplified significantly compared to before.
With this all the error validation that I require
has been added into my template and my template is now updated,
so let's save the changes.
Two other things that I need to add is attribute
called email to this particular field called email.
So, remember that we added the email Validator here.
So, along with the required,
I'm going to add email also to the input field here.
Similarly, for the telnum,
we use the pattern there.
So, I'm going to add in the pattern so this is the input field for the telnum.
So, within the input field I'm going to add pattern is equal to and
the pattern that I'm going to add is
within square brackets zero to nine,
and then put a star there.
So, which means that this is anything zero to nine repeated multiple times.
So, the telephone number can contain any numbers between zero and nine.
Any number of those numbers.
You can also put a minlength and maxlength onto the telnum field
if for your particular country the telephone number has a fixed format,
you can do that too.
So, that can easily be done.
But, in this exercise,
I didn't add in the minlength and maxlength restriction for the telnum here.
Now, that we have done all the updates,
let's save the changes and then go and take a look at the form in the browser.
Going to the browser now,
let's scroll down to the form here.
Let's type in the first name and as you see when you type in only a single character,
then the error message is immediately displayed,
but the moment you type in additional characters that error message will disappear.
Similarly, for the last name.
For the telephone number, if you try to type in anything other than numbers,
then the error messages display.
So, you can type in,
similarly for email, so you see that the email not invalid format will be displayed.
If you don't have the email then it also shows the error message.
But, the moment you type something like this,
then this is considered a valid email format so it will be accepted.
So, that is the set of error messages and the form validation
done completely in code as done in this particular exercise.
So, with this, we complete this exercise.
In this exercise, we have seen the use of the value change is observable,
and we also saw how we can do form validation in our typescript code.
This completes this exercise.
This is a good time for you to do a git commit with
the message reactive forms part three.