Master the basics of Angular 6 reactive forms. In this episode, we build out form examples that solve common challenges like nesting, validation, persistence, and more. https://angularfirebase.com/lessons/basics-reactive-forms-in-angular/

- Reactive Forms Docs https://angular.io/guide/reactive-forms
- Angular CLI Basics https://angularfirebase.com/lessons/basics-angular-cli/
2024-02-04T07:34:43.741Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
15e43100-7e34-47b4-8dcb-5227f2f7bde1
555a568a8e184fa92041305b2942feab54004790a25531fdba99594009d204fa
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
Today, I'm going to show you everything you need to know to start using reactive forms in Angular 6 effectively.
We'll do this by building 5 different forms that start at the absolute basics, then progress on the topics like dynamic form fields, validation, and submitting your form data to a back end database.
Almost all apps use forms in some capacity, so understanding reactive forms is a very valuable skill to have as an Angular developer.
If you're new, make sure to subscribe and grab the source code from angularfirebase.com, and I'll be giving away 3 free hats on Friday.
All you have to do is leave a comment on this video.
I'll be starting off here from an Angular 6 project, and the first thing I'll do is add Angular Material to this project because it has some awesome UI elements for form validation.
You can install it in your project by running ng add angular slash material.
Then I've already generated 5 different components that I'm going to use to demonstrate these different reactive form examples.
If you don't know how to generate components with the CLI, make sure to watch episode 104 from last week.
The reactive forms module isn't included by default, so we're going to import that from Angular forms.
And then we have a bunch of modules that we're importing from Angular Material that handle the different form fields that we wanna use.
Then all of these modules will be added down to the import section, giving us access to these various components and services.
When it comes to Angular Material, there's a whole bunch of different form elements that you can use, so make sure to check out the docs and experiment with some of the examples there.
The first reactive form we'll build starts with the absolute basics.
Let's see how we can set up a few form controls for an email, a message, and a select field for a career.
Then we'll observe the changes to the actual values being entered into this form.
You'll notice that every time we enter something into this form, it updates the value object.
That's because under the hood, the form is using RxJS to treat the form as a reactive real time stream.
Let's go ahead and jump into the type script for this component, and we'll take a look at what we need to build the reactive form.
There's really 2 things you need to know to get started, and that's form group and form builder.
Form group is the actual class that we use to tie different form controls together into a single unified form.
Form builder is just a service that we can use to make building forms easier.
So the first thing you'll do with pretty much any reactive form is to clear the variable type to the form group, and we'll do this in every single one of the demos.
The next thing we'll do is add the form builder service to the constructor of this component.
Then we'll create a data model for this form during NG on a net.
You can think of this as a schema for the data that holds the actual values and validation rules for the fields inside your form.
We call form builder group, and then we set email, and then we can provide an empty string which defines the default value.
Most forms will start off empty, but if you wanna set a default value, you can just define it here.
And that's really all it takes to build a reactive form in the TypeScript.
But you might also want to extract the data from this form in the TypeScript as well.
The form group has a method on it called value changes that returns an observable.
If we subscribe to that observable, it's going to emit the value of the form every time it changes.
That's how I was able to console log every value change in the demo.
Now we need to connect this form group to the HTML and bind it with our Angular Material UI components.
For every reactive form, you'll bind this form group attribute to the form you defined in the TypeScript.
And if you want to see the value of the form in the HTML, you can just call my form value and then use the JSON pipe.
From there, we'll add a material form field and an HTML input with the mat input directive.
So that's just plain Angular material.
To connect it to the reactive form, we call form control name and give it the name of the attribute that we define in the TypeScript.
We can go ahead and follow the same pattern for all of the other fields in our form.
And, again, the only special thing we need to do is call form control name.
Everything else is just a plain Angular Material form.
The one thing you might notice about forms is that there's a lot of real form.
The one thing you might notice about forms is that there's a lot of markup code that you have to deal with.
To avoid leaving you with a big bowl of code soup.
I want to start looking at ways we can keep our reactive forms dry very early on.
The second demo we'll look at is a nested form.
What's special about this form is that we have a parent form group, and then we have a couple of nested forms inside of it for each of these phone numbers.
For the form values.
You can see that we have a nested object inside the form for each of these phone numbers.
Let's take a look at how we can use nesting to keep our forms organized.
We have the same setup as our previous basic form, but this time, we'll create a reusable form group that we can use multiple times in the parent form.
Again, we call form builder group, and then we'll add a couple of default values here for the various parts of the phone number.
Then we'll define the parent in the same way by calling form builder group.
We can nest the schema that we defined for phone numbers multiple times within this form.
So maybe we have a home phone number and also a cell phone number.
Then if we switch over to the HTML, the initial markup is exactly the same, but there's one key difference when dealing with a nested group.
Instead of using form control name, We'll set up a div and pass it the form control group name.
This will be our cell phone group.
Then inside the context of cell phone, we can start adding our inputs, which will take the form control name.
So we can control the cell phone that way, and then we can do the same thing for the home phone as well.
So that works okay if you have 2 phone numbers, but what if the user can dynamically add as many phone numbers as they want?
Using this nested form technique week with 10 phone numbers wouldn't be maintainable at all.
In the next demo, we're going to look at form array, which allows us to dynamically add fields to the form.
Instead of hard coding the form markup, we'll just add a button here that allows the user to add as many phone numbers as they want, and it will add a new field for each one to our reactive form.
You'll notice that instead of a nested object, we now have a nested array of objects.
And because every element in an array has an index, We can allow the user to delete any phone numbers that they've already added to the form.
The initial form setup is very similar, but we also need to import form array from Angular forms.
From there, we can set up a phone's property on the form.
And instead of making this a nested form, it'll be a form array that just starts out with an empty array.
Then the next thing we wanna do is set up a getter to retrieve the phones from the form.
This is technically optional, but getters will make your life a lot easier when working with reactive forms as we'll see here in the upcoming demos.
We can have this method return the phones from the form, and we'll make sure to return that as a form array.
Then the next thing we need to do is set up a function that will run every time a button is clicked to add a new field to the form.
Let's call this the add phone method, and and we'll first set up a variable that defines our form builder group.
Then we can use the getter to return the form array from the reactive form, and we'll call push on it with this new form group.
That handle is adding a form group.
Deleting a form field is even easier.
When we loop over them, we'll be able to get the index.
Then we can simply call form array remove at this index, and that removes it from the reactive form.
The HTML markup is going to start out exactly the same as before.
But now that we have an array, we're going to call form array name with that phone's property.
Then because we're dealing with an array, we're going to need to loop over it.
So I'll say let phone of phone forms controls.
And while performing this loop, we also want to keep track of the index, which we can do with let I equals index.
Now each item in this loop is going to be a form group.
So we need to pass the form group name, which is just the index when dealing with a form group array.
Now we can set up the form fields just like we've done in all the previous examples, passing it the form control name.
The main difference is that we now need to populate this array with some items, which we'll do on a button click.
So we can set up a material button down here, then we'll run our add phone event handler when this button is clicked.
So that button lives outside of the loop, but then to delete an item we want to go back inside of our for loop and add the delete method to a button as well.
So make sure you're inside of ng 4, and then add your button inside of there.
And this time bind it to the delete phone method and pass it the index as an argument.
Now we know how to build large dynamic forms, but we're going to need to validate the user input into these forms.
The one thing I haven't shown you yet is that the reactive form has a whole bunch of different states that it can be in.
For example, it can be valid if it is passing all validation rules.
It's considered dirty if the user has typed into it.
It's considered touched if the user has entered a form field and then left it.
And all of these different states can be applied to the entire form group as a whole, or they can be used for each individual control inside of the form.
And Angular will apply a CSS class for each one of these states to the form so you can use it to control the styling based on the state that the form is in.
Fortunately, Angular Material does most of this for us right out of the box.
As you can see here, if we don't apply a valid email, it's going to give us this message that says your email does not look right.
But as soon as we enter a valid email, that error message goes away.
We can also show different messages based on the type of error that's received.
For example, we might say 5 is too young to use this app, while 99 is too old to use this app.
And then you'll also notice that we have a submit button down here at the bottom.
That button's disabled until the form is completely valid.
That's a very important technique because it often prevents the user from submitting bad data to your back end database.
Let's go into the TypeScript, and we'll import validators from Angular forms.
Angular comes with a bunch of built in validators that will cover 90% of your validation use cases.
For each form property.
We'll set up the default value, and then as the second item in that array, we'll pass another array with a series of validators.
I'd like to point out that you can pass in another array after this with asynchronous validators, but that's a topic for another video.
For right now, we just want to synchronously validate that our email is required and that it's a proper email format.
Then we also want to validate that our password's required, and we can also pass in a regular expression here to make sure that that password meets a certain requirement.
For example, we want to have at least one letter and one number in the password string.
Then when validating numeric values, we can look at the minimum and maximum value, which we can use to set up an age range for the validation.
It shouldn't be confused with min length.
Min length is for strings that will validate how long a string is or how many characters are in that string.
For numeric values.
You wanna use min and max.
So we'll say the minimum age is 18 and the maximum age is 65.
And we also have a checkbox in this form.
So if we want to verify that that checkbox is checked, we can validate that it is required and the value is true.
Now a quick pro tip when working with validations is that you wanna set up a whole bunch of getters for the various fields in your form.
This will just make your HTML way cleaner as you're setting up logic in there to show different error messages for different fields.
Now if we jump over to the HTML, we can use the material error component along with n g f to conditionally show error messages.
Because we set up that getter.
We can just say n g f email is invalid.
And if the email has been touched, then we want to show this error message.
In other words, if the user tried to enter an email and it wasn't correct, we want to notify them that they need to correct that.
Then another cool thing we can do with Angular Material is show hints for more complex values.
For example, for our password, we want to give them a hint that it requires one letter and one number.
Then if they still enter it wrong, we can say your password sucks with a validation error.
So that's pretty cool for just showing error messages when we know the entire form value as incorrect, but we have multiple validators for our age field.
So we might wanna show a different error message based on the type of validation error.
For example, we have a minimum age error.
And if we get that error, we want to show a different error message than if it's the max age.
So if the user enters an age that's less than 18, then we're going to show this message that says your actual age is too young to use this app.
Then we can follow the exact same process for the max age error, but just change some of the details.
If you have a ton of error messages like this, you might want to map them to an object in the TypeScript.
One of the nice things about reactive forms is that you can handle some of the logic in the HTML and some of the logic in the TypeScript depending on your use case.
Then the last thing we'll look at is how to disable the submit button.
For that, we can simply bind the disabled attribute to the form invalid state on the reactive form.
So that's super easy and something you'll probably do on every single reactive form that you build.
We finally reached the 5th and final demo, which is how to submit a form to a back end database.
And naturally, we'll use Cloud Firestore to do that.
So let's take everything we've learned and just build a simple contact form like you would find on any website.
We will validate it.
And then after we know it's been saved in the database, we'll show a success message saying that we received your submission.
If we go into the Firebase console, we should be able to see via data that we entered in the reactive form saved to our back end database.
This next section assumes that you have AngularFire 2 install along with a Firebase project, but you can follow the same principles for any back end.
So we have a basic reactive form following the principles that we've already covered.
What we'll do now is import our Angular Firestore database as well as the tap and first operators from RxJS.
The form submission is asynchronous, so we're gonna have a couple of different state items here, loading and success, which will both start off as false.
The next thing we need to do is create an event handler for when the form is submitted.
This method will be triggered when the user clicks the submit button on the form.
The first thing we'll do is set the loading state to true.
Then we'll grab the current value from the reactive form.
And we do that by calling my form dot value.
Then I will set up a try catch block here so we can catch any errors that might have occurred on the back end.
And then we'll await the Angular Firestore collection, which we'll call contacts to add this form value to the database.
After we've awaited that operation to happen successfully, then we'll set the success state to true.
But if there's any errors, then we'll just go ahead and log those to the console.
Then after that happens, we'll set the loading state back to false.
Then there's really not a whole lot we need to change to the markup.
We want to hide the form once it's been successfully submitted, which we can do by binding the hidden attribute to the success state.
But the most important part is that we listen to this ng submit event, then run our submit handler method, which will send the data to the database.
Then as a final touch down here at the bottom, we'll add a success notification that lets the user know that their data has been saved in the back then.
So hopefully, that gives you a good toolset to build full stack reactive forms in Angular 6.
I'm gonna go ahead and wrap things up there.
If this video helped you, please like and scribe.
And if you're ready to build more advanced features with Angular forms and Firebase, consider becoming a pro member at angularfirebase.com.
You'll get access to new pro videos every week, plus a whole support network designed to help you get your app into production faster.
Thanks for watching, and I'll talk to you soon.

Speaker 0: Today, I'm going to show you everything you need to know to start using reactive forms in Angular 6 effectively. We'll do this by building 5 different forms that start at the absolute basics, then progress on the topics like dynamic form fields, validation, and submitting your form data to a back end database. Almost all apps use forms in some capacity, so understanding reactive forms is a very valuable skill to have as an Angular developer. If you're new, make sure to subscribe and grab the source code from angularfirebase.com, and I'll be giving away 3 free hats on Friday. All you have to do is leave a comment on this video.

I'll be starting off here from an Angular 6 project, and the first thing I'll do is add Angular Material to this project because it has some awesome UI elements for form validation. You can install it in your project by running ng add angular slash material. Then I've already generated 5 different components that I'm going to use to demonstrate these different reactive form examples. If you don't know how to generate components with the CLI, make sure to watch episode 104 from last week. The reactive forms module isn't included by default, so we're going to import that from Angular forms.

And then we have a bunch of modules that we're importing from Angular Material that handle the different form fields that we wanna use. Then all of these modules will be added down to the import section, giving us access to these various components and services. When it comes to Angular Material, there's a whole bunch of different form elements that you can use, so make sure to check out the docs and experiment with some of the examples there. The first reactive form we'll build starts with the absolute basics. Let's see how we can set up a few form controls for an email, a message, and a select field for a career.

Then we'll observe the changes to the actual values being entered into this form. You'll notice that every time we enter something into this form, it updates the value object. That's because under the hood, the form is using RxJS to treat the form as a reactive real time stream. Let's go ahead and jump into the type script for this component, and we'll take a look at what we need to build the reactive form. There's really 2 things you need to know to get started, and that's form group and form builder.

Form group is the actual class that we use to tie different form controls together into a single unified form. Form builder is just a service that we can use to make building forms easier. So the first thing you'll do with pretty much any reactive form is to clear the variable type to the form group, and we'll do this in every single one of the demos. The next thing we'll do is add the form builder service to the constructor of this component. Then we'll create a data model for this form during NG on a net.

You can think of this as a schema for the data that holds the actual values and validation rules for the fields inside your form. We call form builder group, and then we set email, and then we can provide an empty string which defines the default value. Most forms will start off empty, but if you wanna set a default value, you can just define it here. And that's really all it takes to build a reactive form in the TypeScript. But you might also want to extract the data from this form in the TypeScript as well.

The form group has a method on it called value changes that returns an observable. If we subscribe to that observable, it's going to emit the value of the form every time it changes. That's how I was able to console log every value change in the demo. Now we need to connect this form group to the HTML and bind it with our Angular Material UI components. For every reactive form, you'll bind this form group attribute to the form you defined in the TypeScript.

And if you want to see the value of the form in the HTML, you can just call my form value and then use the JSON pipe. From there, we'll add a material form field and an HTML input with the mat input directive. So that's just plain Angular material. To connect it to the reactive form, we call form control name and give it the name of the attribute that we define in the TypeScript. We can go ahead and follow the same pattern for all of the other fields in our form.

And, again, the only special thing we need to do is call form control name. Everything else is just a plain Angular Material form. The one thing you might notice about forms is that there's a lot of real form. The one thing you might notice about forms is that there's a lot of markup code that you have to deal with. To avoid leaving you with a big bowl of code soup.

I want to start looking at ways we can keep our reactive forms dry very early on. The second demo we'll look at is a nested form. What's special about this form is that we have a parent form group, and then we have a couple of nested forms inside of it for each of these phone numbers. For the form values. You can see that we have a nested object inside the form for each of these phone numbers.

Let's take a look at how we can use nesting to keep our forms organized. We have the same setup as our previous basic form, but this time, we'll create a reusable form group that we can use multiple times in the parent form. Again, we call form builder group, and then we'll add a couple of default values here for the various parts of the phone number. Then we'll define the parent in the same way by calling form builder group. We can nest the schema that we defined for phone numbers multiple times within this form.

So maybe we have a home phone number and also a cell phone number. Then if we switch over to the HTML, the initial markup is exactly the same, but there's one key difference when dealing with a nested group. Instead of using form control name, We'll set up a div and pass it the form control group name. This will be our cell phone group. Then inside the context of cell phone, we can start adding our inputs, which will take the form control name.

So we can control the cell phone that way, and then we can do the same thing for the home phone as well. So that works okay if you have 2 phone numbers, but what if the user can dynamically add as many phone numbers as they want? Using this nested form technique week with 10 phone numbers wouldn't be maintainable at all. In the next demo, we're going to look at form array, which allows us to dynamically add fields to the form. Instead of hard coding the form markup, we'll just add a button here that allows the user to add as many phone numbers as they want, and it will add a new field for each one to our reactive form.

You'll notice that instead of a nested object, we now have a nested array of objects. And because every element in an array has an index, We can allow the user to delete any phone numbers that they've already added to the form. The initial form setup is very similar, but we also need to import form array from Angular forms. From there, we can set up a phone's property on the form. And instead of making this a nested form, it'll be a form array that just starts out with an empty array.

Then the next thing we wanna do is set up a getter to retrieve the phones from the form. This is technically optional, but getters will make your life a lot easier when working with reactive forms as we'll see here in the upcoming demos. We can have this method return the phones from the form, and we'll make sure to return that as a form array. Then the next thing we need to do is set up a function that will run every time a button is clicked to add a new field to the form. Let's call this the add phone method, and and we'll first set up a variable that defines our form builder group.

Then we can use the getter to return the form array from the reactive form, and we'll call push on it with this new form group. That handle is adding a form group. Deleting a form field is even easier. When we loop over them, we'll be able to get the index. Then we can simply call form array remove at this index, and that removes it from the reactive form.

The HTML markup is going to start out exactly the same as before. But now that we have an array, we're going to call form array name with that phone's property. Then because we're dealing with an array, we're going to need to loop over it. So I'll say let phone of phone forms controls. And while performing this loop, we also want to keep track of the index, which we can do with let I equals index.

Now each item in this loop is going to be a form group. So we need to pass the form group name, which is just the index when dealing with a form group array. Now we can set up the form fields just like we've done in all the previous examples, passing it the form control name. The main difference is that we now need to populate this array with some items, which we'll do on a button click. So we can set up a material button down here, then we'll run our add phone event handler when this button is clicked.

So that button lives outside of the loop, but then to delete an item we want to go back inside of our for loop and add the delete method to a button as well. So make sure you're inside of ng 4, and then add your button inside of there. And this time bind it to the delete phone method and pass it the index as an argument. Now we know how to build large dynamic forms, but we're going to need to validate the user input into these forms. The one thing I haven't shown you yet is that the reactive form has a whole bunch of different states that it can be in.

For example, it can be valid if it is passing all validation rules. It's considered dirty if the user has typed into it. It's considered touched if the user has entered a form field and then left it. And all of these different states can be applied to the entire form group as a whole, or they can be used for each individual control inside of the form. And Angular will apply a CSS class for each one of these states to the form so you can use it to control the styling based on the state that the form is in.

Fortunately, Angular Material does most of this for us right out of the box. As you can see here, if we don't apply a valid email, it's going to give us this message that says your email does not look right. But as soon as we enter a valid email, that error message goes away. We can also show different messages based on the type of error that's received. For example, we might say 5 is too young to use this app, while 99 is too old to use this app.

And then you'll also notice that we have a submit button down here at the bottom. That button's disabled until the form is completely valid. That's a very important technique because it often prevents the user from submitting bad data to your back end database. Let's go into the TypeScript, and we'll import validators from Angular forms. Angular comes with a bunch of built in validators that will cover 90% of your validation use cases.

For each form property. We'll set up the default value, and then as the second item in that array, we'll pass another array with a series of validators. I'd like to point out that you can pass in another array after this with asynchronous validators, but that's a topic for another video. For right now, we just want to synchronously validate that our email is required and that it's a proper email format. Then we also want to validate that our password's required, and we can also pass in a regular expression here to make sure that that password meets a certain requirement.

For example, we want to have at least one letter and one number in the password string. Then when validating numeric values, we can look at the minimum and maximum value, which we can use to set up an age range for the validation. It shouldn't be confused with min length. Min length is for strings that will validate how long a string is or how many characters are in that string. For numeric values.

You wanna use min and max. So we'll say the minimum age is 18 and the maximum age is 65. And we also have a checkbox in this form. So if we want to verify that that checkbox is checked, we can validate that it is required and the value is true. Now a quick pro tip when working with validations is that you wanna set up a whole bunch of getters for the various fields in your form.

This will just make your HTML way cleaner as you're setting up logic in there to show different error messages for different fields. Now if we jump over to the HTML, we can use the material error component along with n g f to conditionally show error messages. Because we set up that getter. We can just say n g f email is invalid. And if the email has been touched, then we want to show this error message.

In other words, if the user tried to enter an email and it wasn't correct, we want to notify them that they need to correct that. Then another cool thing we can do with Angular Material is show hints for more complex values. For example, for our password, we want to give them a hint that it requires one letter and one number. Then if they still enter it wrong, we can say your password sucks with a validation error. So that's pretty cool for just showing error messages when we know the entire form value as incorrect, but we have multiple validators for our age field.

So we might wanna show a different error message based on the type of validation error. For example, we have a minimum age error. And if we get that error, we want to show a different error message than if it's the max age. So if the user enters an age that's less than 18, then we're going to show this message that says your actual age is too young to use this app. Then we can follow the exact same process for the max age error, but just change some of the details.

If you have a ton of error messages like this, you might want to map them to an object in the TypeScript. One of the nice things about reactive forms is that you can handle some of the logic in the HTML and some of the logic in the TypeScript depending on your use case. Then the last thing we'll look at is how to disable the submit button. For that, we can simply bind the disabled attribute to the form invalid state on the reactive form. So that's super easy and something you'll probably do on every single reactive form that you build.

We finally reached the 5th and final demo, which is how to submit a form to a back end database. And naturally, we'll use Cloud Firestore to do that. So let's take everything we've learned and just build a simple contact form like you would find on any website. We will validate it. And then after we know it's been saved in the database, we'll show a success message saying that we received your submission.

If we go into the Firebase console, we should be able to see via data that we entered in the reactive form saved to our back end database. This next section assumes that you have AngularFire 2 install along with a Firebase project, but you can follow the same principles for any back end. So we have a basic reactive form following the principles that we've already covered. What we'll do now is import our Angular Firestore database as well as the tap and first operators from RxJS. The form submission is asynchronous, so we're gonna have a couple of different state items here, loading and success, which will both start off as false.

The next thing we need to do is create an event handler for when the form is submitted. This method will be triggered when the user clicks the submit button on the form. The first thing we'll do is set the loading state to true. Then we'll grab the current value from the reactive form. And we do that by calling my form dot value.

Then I will set up a try catch block here so we can catch any errors that might have occurred on the back end. And then we'll await the Angular Firestore collection, which we'll call contacts to add this form value to the database. After we've awaited that operation to happen successfully, then we'll set the success state to true. But if there's any errors, then we'll just go ahead and log those to the console. Then after that happens, we'll set the loading state back to false.

Then there's really not a whole lot we need to change to the markup. We want to hide the form once it's been successfully submitted, which we can do by binding the hidden attribute to the success state. But the most important part is that we listen to this ng submit event, then run our submit handler method, which will send the data to the database. Then as a final touch down here at the bottom, we'll add a success notification that lets the user know that their data has been saved in the back then. So hopefully, that gives you a good toolset to build full stack reactive forms in Angular 6.

I'm gonna go ahead and wrap things up there. If this video helped you, please like and scribe. And if you're ready to build more advanced features with Angular forms and Firebase, consider becoming a pro member at angularfirebase.com. You'll get access to new pro videos every week, plus a whole support network designed to help you get your app into production faster. Thanks for watching, and I'll talk to you soon.
Today, I'm going to show you everything you need to know to start using reactive forms in Angular 6 effectively. We'll do this by building 5 different forms that start at the absolute basics, then progress on the topics like dynamic form fields, validation, and submitting your form data to a back end database. Almost all apps use forms in some capacity, so understanding reactive forms is a very valuable skill to have as an Angular developer. If you're new, make sure to subscribe and grab the source code from angularfirebase.com, and I'll be giving away 3 free hats on Friday. All you have to do is leave a comment on this video. I'll be starting off here from an Angular 6 project, and the first thing I'll do is add Angular Material to this project because it has some awesome UI elements for form validation. You can install it in your project by running ng add angular slash material. Then I've already generated 5 different components that I'm going to use to demonstrate these different reactive form examples. If you don't know how to generate components with the CLI, make sure to watch episode 104 from last week. The reactive forms module isn't included by default, so we're going to import that from Angular forms. And then we have a bunch of modules that we're importing from Angular Material that handle the different form fields that we wanna use. Then all of these modules will be added down to the import section, giving us access to these various components and services. When it comes to Angular Material, there's a whole bunch of different form elements that you can use, so make sure to check out the docs and experiment with some of the examples there. The first reactive form we'll build starts with the absolute basics. Let's see how we can set up a few form controls for an email, a message, and a select field for a career. Then we'll observe the changes to the actual values being entered into this form. You'll notice that every time we enter something into this form, it updates the value object. That's because under the hood, the form is using RxJS to treat the form as a reactive real time stream. Let's go ahead and jump into the type script for this component, and we'll take a look at what we need to build the reactive form. There's really 2 things you need to know to get started, and that's form group and form builder. Form group is the actual class that we use to tie different form controls together into a single unified form. Form builder is just a service that we can use to make building forms easier. So the first thing you'll do with pretty much any reactive form is to clear the variable type to the form group, and we'll do this in every single one of the demos. The next thing we'll do is add the form builder service to the constructor of this component. Then we'll create a data model for this form during NG on a net. You can think of this as a schema for the data that holds the actual values and validation rules for the fields inside your form. We call form builder group, and then we set email, and then we can provide an empty string which defines the default value. Most forms will start off empty, but if you wanna set a default value, you can just define it here. And that's really all it takes to build a reactive form in the TypeScript. But you might also want to extract the data from this form in the TypeScript as well. The form group has a method on it called value changes that returns an observable. If we subscribe to that observable, it's going to emit the value of the form every time it changes. That's how I was able to console log every value change in the demo. Now we need to connect this form group to the HTML and bind it with our Angular Material UI components. For every reactive form, you'll bind this form group attribute to the form you defined in the TypeScript. And if you want to see the value of the form in the HTML, you can just call my form value and then use the JSON pipe. From there, we'll add a material form field and an HTML input with the mat input directive. So that's just plain Angular material. To connect it to the reactive form, we call form control name and give it the name of the attribute that we define in the TypeScript. We can go ahead and follow the same pattern for all of the other fields in our form. And, again, the only special thing we need to do is call form control name. Everything else is just a plain Angular Material form. The one thing you might notice about forms is that there's a lot of real form. The one thing you might notice about forms is that there's a lot of markup code that you have to deal with. To avoid leaving you with a big bowl of code soup. I want to start looking at ways we can keep our reactive forms dry very early on. The second demo we'll look at is a nested form. What's special about this form is that we have a parent form group, and then we have a couple of nested forms inside of it for each of these phone numbers. For the form values. You can see that we have a nested object inside the form for each of these phone numbers. Let's take a look at how we can use nesting to keep our forms organized. We have the same setup as our previous basic form, but this time, we'll create a reusable form group that we can use multiple times in the parent form. Again, we call form builder group, and then we'll add a couple of default values here for the various parts of the phone number. Then we'll define the parent in the same way by calling form builder group. We can nest the schema that we defined for phone numbers multiple times within this form. So maybe we have a home phone number and also a cell phone number. Then if we switch over to the HTML, the initial markup is exactly the same, but there's one key difference when dealing with a nested group. Instead of using form control name, We'll set up a div and pass it the form control group name. This will be our cell phone group.
Then inside the context of cell phone, we can start adding our inputs, which will take the form control name. So we can control the cell phone that way, and then we can do the same thing for the home phone as well. So that works okay if you have 2 phone numbers, but what if the user can dynamically add as many phone numbers as they want?
phones
Using this nested form technique week with 10 phone numbers wouldn't be maintainable at all. In the next demo, we're going to look at form array, which allows us to dynamically add fields to the form. Instead of hard coding the form markup, we'll just add a button here that allows the user to add as many phone numbers as they want, and it will add a new field for each one to our reactive form. You'll notice that instead of a nested object, we now have a nested array of objects. And because every element in an array has an index, We can allow the user to delete any phone numbers that they've already added to the form. The initial form setup is very similar, but we also need to import form array from Angular forms. From there, we can set up a phone's property on the form. And instead of making this a nested form, it'll be a form array that just starts out with an empty array. Then the next thing we wanna do is set up a getter to retrieve the phones from the form. This is technically optional, but getters will make your life a lot easier when working with reactive forms as we'll see here in the upcoming demos. We can have this method return the phones from the form, and we'll make sure to return that as a form array. Then the next thing we need to do is set up a function that will run every time a button is clicked to add a new field to the form. Let's call this the add phone method, and and we'll first set up a variable that defines our form builder group. Then we can use the getter to return the form array from the reactive form, and we'll call push on it with this new form group. That handle is adding a form group. Deleting a form field is even easier. When we loop over them, we'll be able to get the index. Then we can simply call form array remove at this index, and that removes it from the reactive form. The HTML markup is going to start out exactly the same as before. But now that we have an array, we're going to call form array name with that phone's property. Then because we're dealing with an array, we're going to need to loop over it. So I'll say let phone of phone forms controls. And while performing this loop, we also want to keep track of the index, which we can do with let I equals index. Now each item in this loop is going to be a form group. So we need to pass the form group name, which is just the index when dealing with a form group array. Now we can set up the form fields just like we've done in all the previous examples, passing it the form control name. The main difference is that we now need to populate this array with some items, which we'll do on a button click. So we can set up a material button down here, then we'll run our add phone event handler when this button is clicked. So that button lives outside of the loop, but then to delete an item we want to go back inside of our for loop and add the delete method to a button as well. So make sure you're inside of ng 4, and then add your button inside of there. And this time bind it to the delete phone method and pass it the index as an argument. Now we know how to build large dynamic forms, but we're going to need to validate the user input into these forms. The one thing I haven't shown you yet is that the reactive form has a whole bunch of different states that it can be in. For example, it can be valid if it is passing all validation rules. It's considered dirty if the user has typed into it. It's considered touched if the user has entered a form field and then left it. And all of these different states can be applied to the entire form group as a whole, or they can be used for each individual control inside of the form. And Angular will apply a CSS class for each one of these states to the form so you can use it to control the styling based on the state that the form is in.
Fortunately, Angular Material does most of this for us right out of the box. As you can see here, if we don't apply a valid email, it's going to give us this message that says your email does not look right. But as soon as we enter a valid email, that error message goes away. We can also show different messages based on the type of error that's received. For example, we might say 5 is too young to use this app, while 99 is too old to use this app.
email
And then you'll also notice that we have a submit button down here at the bottom. That button's disabled until the form is completely valid. That's a very important technique because it often prevents the user from submitting bad data to your back end database. Let's go into the TypeScript, and we'll import validators from Angular forms. Angular comes with a bunch of built in validators that will cover 90% of your validation use cases. For each form property. We'll set up the default value, and then as the second item in that array, we'll pass another array with a series of validators.
I'd like to point out that you can pass in another array after this with asynchronous validators, but that's a topic for another video. For right now, we just want to synchronously validate that our email is required and that it's a proper email format. Then we also want to validate that our password's required, and we can also pass in a regular expression here to make sure that that password meets a certain requirement.
email
For example, we want to have at least one letter and one number in the password string. Then when validating numeric values, we can look at the minimum and maximum value, which we can use to set up an age range for the validation. It shouldn't be confused with min length. Min length is for strings that will validate how long a string is or how many characters are in that string. For numeric values. You wanna use min and max. So we'll say the minimum age is 18 and the maximum age is 65. And we also have a checkbox in this form. So if we want to verify that that checkbox is checked, we can validate that it is required and the value is true. Now a quick pro tip when working with validations is that you wanna set up a whole bunch of getters for the various fields in your form. This will just make your HTML way cleaner as you're setting up logic in there to show different error messages for different fields. Now if we jump over to the HTML, we can use the material error component along with n g f to conditionally show error messages.
Because we set up that getter. We can just say n g f email is invalid. And if the email has been touched, then we want to show this error message. In other words, if the user tried to enter an email and it wasn't correct, we want to notify them that they need to correct that.
email
Then another cool thing we can do with Angular Material is show hints for more complex values. For example, for our password, we want to give them a hint that it requires one letter and one number. Then if they still enter it wrong, we can say your password sucks with a validation error. So that's pretty cool for just showing error messages when we know the entire form value as incorrect, but we have multiple validators for our age field. So we might wanna show a different error message based on the type of validation error. For example, we have a minimum age error. And if we get that error, we want to show a different error message than if it's the max age. So if the user enters an age that's less than 18, then we're going to show this message that says your actual age is too young to use this app. Then we can follow the exact same process for the max age error, but just change some of the details. If you have a ton of error messages like this, you might want to map them to an object in the TypeScript. One of the nice things about reactive forms is that you can handle some of the logic in the HTML and some of the logic in the TypeScript depending on your use case. Then the last thing we'll look at is how to disable the submit button. For that, we can simply bind the disabled attribute to the form invalid state on the reactive form. So that's super easy and something you'll probably do on every single reactive form that you build. We finally reached the 5th and final demo, which is how to submit a form to a back end database. And naturally, we'll use Cloud Firestore to do that. So let's take everything we've learned and just build a simple contact form like you would find on any website. We will validate it. And then after we know it's been saved in the database, we'll show a success message saying that we received your submission. If we go into the Firebase console, we should be able to see via data that we entered in the reactive form saved to our back end database. This next section assumes that you have AngularFire 2 install along with a Firebase project, but you can follow the same principles for any back end. So we have a basic reactive form following the principles that we've already covered. What we'll do now is import our Angular Firestore database as well as the tap and first operators from RxJS. The form submission is asynchronous, so we're gonna have a couple of different state items here, loading and success, which will both start off as false. The next thing we need to do is create an event handler for when the form is submitted. This method will be triggered when the user clicks the submit button on the form. The first thing we'll do is set the loading state to true. Then we'll grab the current value from the reactive form. And we do that by calling my form dot value. Then I will set up a try catch block here so we can catch any errors that might have occurred on the back end. And then we'll await the Angular Firestore collection, which we'll call contacts to add this form value to the database. After we've awaited that operation to happen successfully, then we'll set the success state to true. But if there's any errors, then we'll just go ahead and log those to the console. Then after that happens, we'll set the loading state back to false. Then there's really not a whole lot we need to change to the markup. We want to hide the form once it's been successfully submitted, which we can do by binding the hidden attribute to the success state. But the most important part is that we listen to this ng submit event, then run our submit handler method, which will send the data to the database. Then as a final touch down here at the bottom, we'll add a success notification that lets the user know that their data has been saved in the back then. So hopefully, that gives you a good toolset to build full stack reactive forms in Angular 6. I'm gonna go ahead and wrap things up there.
If this video helped you, please like and scribe. And if you're ready to build more advanced features with Angular forms and Firebase, consider becoming a pro member at angularfirebase.com. You'll get access to new pro videos every week, plus a whole support network designed to help you get your app into production faster. Thanks for watching, and I'll talk to you soon.
video gaming
youtube
streaming
multimedia
Today, I'm going to show you everything you need to know to start using reactive forms in Angular 6 effectively. We'll do this by building 5 different forms that start at the absolute basics, then progress on the topics like dynamic form fields, validation, and submitting your form data to a back end database. Almost all apps use forms in some capacity, so understanding reactive forms is a very valuable skill to have as an Angular developer. If you're new, make sure to subscribe and grab the source code from angularfirebase.com, and I'll be giving away 3 free hats on Friday. All you have to do is leave a comment on this video. I'll be starting off here from an Angular 6 project, and the first thing I'll do is add Angular Material to this project because it has some awesome UI elements for form validation. You can install it in your project by running ng add angular slash material. Then I've already generated 5 different components that I'm going to use to demonstrate these different reactive form examples. If you don't know how to generate components with the CLI, make sure to watch episode 104 from last week. The reactive forms module isn't included by default, so we're going to import that from Angular forms. And then we have a bunch of modules that we're importing from Angular Material that handle the different form fields that we wanna use. Then all of these modules will be added down to the import section, giving us access to these various components and services. When it comes to Angular Material, there's a whole bunch of different form elements that you can use, so make sure to check out the docs and experiment with some of the examples there. The first reactive form we'll build starts with the absolute basics. Let's see how we can set up a few form controls for an email, a message, and a select field for a career. Then we'll observe the changes to the actual values being entered into this form. You'll notice that every time we enter something into this form, it updates the value object. That's because under the hood, the form is using RxJS to treat the form as a reactive real time stream. Let's go ahead and jump into the type script for this component, and we'll take a look at what we need to build the reactive form. There's really 2 things you need to know to get started, and that's form group and form builder. Form group is the actual class that we use to tie different form controls together into a single unified form. Form builder is just a service that we can use to make building forms easier. So the first thing you'll do with pretty much any reactive form is to clear the variable type to the form group, and we'll do this in every single one of the demos. The next thing we'll do is add the form builder service to the constructor of this component. Then we'll create a data model for this form during NG on a net. You can think of this as a schema for the data that holds the actual values and validation rules for the fields inside your form. We call form builder group, and then we set email, and then we can provide an empty string which defines the default value. Most forms will start off empty, but if you wanna set a default value, you can just define it here. And that's really all it takes to build a reactive form in the TypeScript. But you might also want to extract the data from this form in the TypeScript as well. The form group has a method on it called value changes that returns an observable. If we subscribe to that observable, it's going to emit the value of the form every time it changes. That's how I was able to console log every value change in the demo. Now we need to connect this form group to the HTML and bind it with our Angular Material UI components. For every reactive form, you'll bind this form group attribute to the form you defined in the TypeScript. And if you want to see the value of the form in the HTML, you can just call my form value and then use the JSON pipe. From there, we'll add a material form field and an HTML input with the mat input directive. So that's just plain Angular material. To connect it to the reactive form, we call form control name and give it the name of the attribute that we define in the TypeScript. We can go ahead and follow the same pattern for all of the other fields in our form. And, again, the only special thing we need to do is call form control name. Everything else is just a plain Angular Material form. The one thing you might notice about forms is that there's a lot of real form. The one thing you might notice about forms is that there's a lot of markup code that you have to deal with. To avoid leaving you with a big bowl of code soup. I want to start looking at ways we can keep our reactive forms dry very early on. The second demo we'll look at is a nested form. What's special about this form is that we have a parent form group, and then we have a couple of nested forms inside of it for each of these phone numbers. For the form values. You can see that we have a nested object inside the form for each of these phone numbers. Let's take a look at how we can use nesting to keep our forms organized. We have the same setup as our previous basic form, but this time, we'll create a reusable form group that we can use multiple times in the parent form. Again, we call form builder group, and then we'll add a couple of default values here for the various parts of the phone number. Then we'll define the parent in the same way by calling form builder group. We can nest the schema that we defined for phone numbers multiple times within this form. So maybe we have a home phone number and also a cell phone number. Then if we switch over to the HTML, the initial markup is exactly the same, but there's one key difference when dealing with a nested group. Instead of using form control name, We'll set up a div and pass it the form control group name. This will be our cell phone group. Then inside the context of cell phone, we can start adding our inputs, which will take the form control name. So we can control the cell phone that way, and then we can do the same thing for the home phone as well. So that works okay if you have 2 phone numbers, but what if the user can dynamically add as many phone numbers as they want? Using this nested form technique week with 10 phone numbers wouldn't be maintainable at all. In the next demo, we're going to look at form array, which allows us to dynamically add fields to the form. Instead of hard coding the form markup, we'll just add a button here that allows the user to add as many phone numbers as they want, and it will add a new field for each one to our reactive form. You'll notice that instead of a nested object, we now have a nested array of objects. And because every element in an array has an index, We can allow the user to delete any phone numbers that they've already added to the form. The initial form setup is very similar, but we also need to import form array from Angular forms. From there, we can set up a phone's property on the form. And instead of making this a nested form, it'll be a form array that just starts out with an empty array. Then the next thing we wanna do is set up a getter to retrieve the phones from the form. This is technically optional, but getters will make your life a lot easier when working with reactive forms as we'll see here in the upcoming demos. We can have this method return the phones from the form, and we'll make sure to return that as a form array. Then the next thing we need to do is set up a function that will run every time a button is clicked to add a new field to the form. Let's call this the add phone method, and and we'll first set up a variable that defines our form builder group. Then we can use the getter to return the form array from the reactive form, and we'll call push on it with this new form group. That handle is adding a form group. Deleting a form field is even easier. When we loop over them, we'll be able to get the index. Then we can simply call form array remove at this index, and that removes it from the reactive form. The HTML markup is going to start out exactly the same as before. But now that we have an array, we're going to call form array name with that phone's property. Then because we're dealing with an array, we're going to need to loop over it. So I'll say let phone of phone forms controls. And while performing this loop, we also want to keep track of the index, which we can do with let I equals index. Now each item in this loop is going to be a form group. So we need to pass the form group name, which is just the index when dealing with a form group array. Now we can set up the form fields just like we've done in all the previous examples, passing it the form control name. The main difference is that we now need to populate this array with some items, which we'll do on a button click. So we can set up a material button down here, then we'll run our add phone event handler when this button is clicked. So that button lives outside of the loop, but then to delete an item we want to go back inside of our for loop and add the delete method to a button as well. So make sure you're inside of ng 4, and then add your button inside of there. And this time bind it to the delete phone method and pass it the index as an argument. Now we know how to build large dynamic forms, but we're going to need to validate the user input into these forms. The one thing I haven't shown you yet is that the reactive form has a whole bunch of different states that it can be in. For example, it can be valid if it is passing all validation rules. It's considered dirty if the user has typed into it. It's considered touched if the user has entered a form field and then left it. And all of these different states can be applied to the entire form group as a whole, or they can be used for each individual control inside of the form. And Angular will apply a CSS class for each one of these states to the form so you can use it to control the styling based on the state that the form is in. Fortunately, Angular Material does most of this for us right out of the box. As you can see here, if we don't apply a valid email, it's going to give us this message that says your email does not look right. But as soon as we enter a valid email, that error message goes away. We can also show different messages based on the type of error that's received. For example, we might say 5 is too young to use this app, while 99 is too old to use this app. And then you'll also notice that we have a submit button down here at the bottom. That button's disabled until the form is completely valid. That's a very important technique because it often prevents the user from submitting bad data to your back end database. Let's go into the TypeScript, and we'll import validators from Angular forms. Angular comes with a bunch of built in validators that will cover 90% of your validation use cases. For each form property. We'll set up the default value, and then as the second item in that array, we'll pass another array with a series of validators. I'd like to point out that you can pass in another array after this with asynchronous validators, but that's a topic for another video. For right now, we just want to synchronously validate that our email is required and that it's a proper email format. Then we also want to validate that our password's required, and we can also pass in a regular expression here to make sure that that password meets a certain requirement. For example, we want to have at least one letter and one number in the password string. Then when validating numeric values, we can look at the minimum and maximum value, which we can use to set up an age range for the validation. It shouldn't be confused with min length. Min length is for strings that will validate how long a string is or how many characters are in that string. For numeric values. You wanna use min and max. So we'll say the minimum age is 18 and the maximum age is 65. And we also have a checkbox in this form. So if we want to verify that that checkbox is checked, we can validate that it is required and the value is true. Now a quick pro tip when working with validations is that you wanna set up a whole bunch of getters for the various fields in your form. This will just make your HTML way cleaner as you're setting up logic in there to show different error messages for different fields. Now if we jump over to the HTML, we can use the material error component along with n g f to conditionally show error messages. Because we set up that getter. We can just say n g f email is invalid. And if the email has been touched, then we want to show this error message. In other words, if the user tried to enter an email and it wasn't correct, we want to notify them that they need to correct that. Then another cool thing we can do with Angular Material is show hints for more complex values. For example, for our password, we want to give them a hint that it requires one letter and one number. Then if they still enter it wrong, we can say your password sucks with a validation error. So that's pretty cool for just showing error messages when we know the entire form value as incorrect, but we have multiple validators for our age field. So we might wanna show a different error message based on the type of validation error. For example, we have a minimum age error. And if we get that error, we want to show a different error message than if it's the max age. So if the user enters an age that's less than 18, then we're going to show this message that says your actual age is too young to use this app. Then we can follow the exact same process for the max age error, but just change some of the details. If you have a ton of error messages like this, you might want to map them to an object in the TypeScript. One of the nice things about reactive forms is that you can handle some of the logic in the HTML and some of the logic in the TypeScript depending on your use case. Then the last thing we'll look at is how to disable the submit button. For that, we can simply bind the disabled attribute to the form invalid state on the reactive form. So that's super easy and something you'll probably do on every single reactive form that you build. We finally reached the 5th and final demo, which is how to submit a form to a back end database. And naturally, we'll use Cloud Firestore to do that. So let's take everything we've learned and just build a simple contact form like you would find on any website. We will validate it. And then after we know it's been saved in the database, we'll show a success message saying that we received your submission. If we go into the Firebase console, we should be able to see via data that we entered in the reactive form saved to our back end database. This next section assumes that you have AngularFire 2 install along with a Firebase project, but you can follow the same principles for any back end. So we have a basic reactive form following the principles that we've already covered. What we'll do now is import our Angular Firestore database as well as the tap and first operators from RxJS. The form submission is asynchronous, so we're gonna have a couple of different state items here, loading and success, which will both start off as false. The next thing we need to do is create an event handler for when the form is submitted. This method will be triggered when the user clicks the submit button on the form. The first thing we'll do is set the loading state to true. Then we'll grab the current value from the reactive form. And we do that by calling my form dot value. Then I will set up a try catch block here so we can catch any errors that might have occurred on the back end. And then we'll await the Angular Firestore collection, which we'll call contacts to add this form value to the database. After we've awaited that operation to happen successfully, then we'll set the success state to true. But if there's any errors, then we'll just go ahead and log those to the console. Then after that happens, we'll set the loading state back to false. Then there's really not a whole lot we need to change to the markup. We want to hide the form once it's been successfully submitted, which we can do by binding the hidden attribute to the success state. But the most important part is that we listen to this ng submit event, then run our submit handler method, which will send the data to the database. Then as a final touch down here at the bottom, we'll add a success notification that lets the user know that their data has been saved in the back then. So hopefully, that gives you a good toolset to build full stack reactive forms in Angular 6. I'm gonna go ahead and wrap things up there. If this video helped you, please like and scribe. And if you're ready to build more advanced features with Angular forms and Firebase, consider becoming a pro member at angularfirebase.com. You'll get access to new pro videos every week, plus a whole support network designed to help you get your app into production faster. Thanks for watching, and I'll talk to you soon.
Today,
today
I'm
i'm
going
going
to
to
show
show
you
you
everything
everything
you
you
need
need
to
to
know
know
to
to
start
start
using
using
reactive
reactive
forms
forms
in
in
Angular
angular
6
6
effectively.
effectively
We'll
we'll
do
do
this
this
by
by
building
building
5
5
different
different
forms
forms
that
that
start
start
at
at
the
the
absolute
absolute
basics,
basics
then
then
progress
progress
on
on
the
the
topics
topics
like
like
dynamic
dynamic
form
form
fields,
fields
validation,
validation
and
and
submitting
submitting
your
your
form
form
data
data
to
to
a
a
back
back
end
end
database.
database
Almost
almost
all
all
apps
apps
use
use
forms
forms
in
in
some
some
capacity,
capacity
so
so
understanding
understanding
reactive
reactive
forms
forms
is
is
a
a
very
very
valuable
valuable
skill
skill
to
to
have
have
as
as
an
an
Angular
angular
developer.
developer
If
if
you're
you're
new,
new
make
make
sure
sure
to
to
subscribe
subscribe
and
and
grab
grab
the
the
source
source
code
code
from
from
angularfirebase.com,
angularfirebase.com
and
and
I'll
i'll
be
be
giving
giving
away
away
3
3
free
free
hats
hats
on
on
Friday.
friday
All
all
you
you
have
have
to
to
do
do
is
is
leave
leave
a
a
comment
comment
on
on
this
this
video.
video
I'll
i'll
be
be
starting
starting
off
off
here
here
from
from
an
an
Angular
angular
6
6
project,
project
and
and
the
the
first
first
thing
thing
I'll
i'll
do
do
is
is
add
add
Angular
angular
Material
material
to
to
this
this
project
project
because
because
it
it
has
has
some
some
awesome
awesome
UI
ui
elements
elements
for
for
form
form
validation.
validation
You
you
can
can
install
install
it
it
in
in
your
your
project
project
by
by
running
running
ng
ng
add
add
angular
angular
slash
slash
material.
material
Then
then
I've
i've
already
already
generated
generated
5
5
different
different
components
components
that
that
I'm
i'm
going
going
to
to
use
use
to
to
demonstrate
demonstrate
these
these
different
different
reactive
reactive
form
form
examples.
examples
If
if
you
you
don't
don't
know
know
how
how
to
to
generate
generate
components
components
with
with
the
the
CLI,
cli
make
make
sure
sure
to
to
watch
watch
episode
episode
104
104
from
from
last
last
week.
week
The
the
reactive
reactive
forms
forms
module
module
isn't
isn't
included
included
by
by
default,
default
so
so
we're
we're
going
going
to
to
import
import
that
that
from
from
Angular
angular
forms.
forms
And
and
then
then
we
we
have
have
a
a
bunch
bunch
of
of
modules
modules
that
that
we're
we're
importing
importing
from
from
Angular
angular
Material
material
that
that
handle
handle
the
the
different
different
form
form
fields
fields
that
that
we
we
wanna
wanna
use.
use
Then
then
all
all
of
of
these
these
modules
modules
will
will
be
be
added
added
down
down
to
to
the
the
import
import
section,
section
giving
giving
us
us
access
access
to
to
these
these
various
various
components
components
and
and
services.
services
When
when
it
it
comes
comes
to
to
Angular
angular
Material,
material
there's
there's
a
a
whole
whole
bunch
bunch
of
of
different
different
form
form
elements
elements
that
that
you
you
can
can
use,
use
so
so
make
make
sure
sure
to
to
check
check
out
out
the
the
docs
docs
and
and
experiment
experiment
with
with
some
some
of
of
the
the
examples
examples
there.
there
The
the
first
first
reactive
reactive
form
form
we'll
we'll
build
build
starts
starts
with
with
the
the
absolute
absolute
basics.
basics
Let's
let's
see
see
how
how
we
we
can
can
set
set
up
up
a
a
few
few
form
form
controls
controls
for
for
an
an
email,
email
a
a
message,
message
and
and
a
a
select
select
field
field
for
for
a
a
career.
career
Then
then
we'll
we'll
observe
observe
the
the
changes
changes
to
to
the
the
actual
actual
values
values
being
being
entered
entered
into
into
this
this
form.
form
You'll
you'll
notice
notice
that
that
every
every
time
time
we
we
enter
enter
something
something
into
into
this
this
form,
form
it
it
updates
updates
the
the
value
value
object.
object
That's
that's
because
because
under
under
the
the
hood,
hood
the
the
form
form
is
is
using
using
RxJS
rxjs
to
to
treat
treat
the
the
form
form
as
as
a
a
reactive
reactive
real
real
time
time
stream.
stream
Let's
let's
go
go
ahead
ahead
and
and
jump
jump
into
into
the
the
type
type
script
script
for
for
this
this
component,
component
and
and
we'll
we'll
take
take
a
a
look
look
at
at
what
what
we
we
need
need
to
to
build
build
the
the
reactive
reactive
form.
form
There's
there's
really
really
2
2
things
things
you
you
need
need
to
to
know
know
to
to
get
get
started,
started
and
and
that's
that's
form
form
group
group
and
and
form
form
builder.
builder
Form
form
group
group
is
is
the
the
actual
actual
class
class
that
that
we
we
use
use
to
to
tie
tie
different
different
form
form
controls
controls
together
together
into
into
a
a
single
single
unified
unified
form.
form
Form
form
builder
builder
is
is
just
just
a
a
service
service
that
that
we
we
can
can
use
use
to
to
make
make
building
building
forms
forms
easier.
easier
So
so
the
the
first
first
thing
thing
you'll
you'll
do
do
with
with
pretty
pretty
much
much
any
any
reactive
reactive
form
form
is
is
to
to
clear
clear
the
the
variable
variable
type
type
to
to
the
the
form
form
group,
group
and
and
we'll
we'll
do
do
this
this
in
in
every
every
single
single
one
one
of
of
the
the
demos.
demos
The
the
next
next
thing
thing
we'll
we'll
do
do
is
is
add
add
the
the
form
form
builder
builder
service
service
to
to
the
the
constructor
constructor
of
of
this
this
component.
component
Then
then
we'll
we'll
create
create
a
a
data
data
model
model
for
for
this
this
form
form
during
during
NG
ng
on
on
a
a
net.
net
You
you
can
can
think
think
of
of
this
this
as
as
a
a
schema
schema
for
for
the
the
data
data
that
that
holds
holds
the
the
actual
actual
values
values
and
and
validation
validation
rules
rules
for
for
the
the
fields
fields
inside
inside
your
your
form.
form
We
we
call
call
form
form
builder
builder
group,
group
and
and
then
then
we
we
set
set
email,
email
and
and
then
then
we
we
can
can
provide
provide
an
an
empty
empty
string
string
which
which
defines
defines
the
the
default
default
value.
value
Most
most
forms
forms
will
will
start
start
off
off
empty,
empty
but
but
if
if
you
you
wanna
wanna
set
set
a
a
default
default
value,
value
you
you
can
can
just
just
define
define
it
it
here.
here
And
and
that's
that's
really
really
all
all
it
it
takes
takes
to
to
build
build
a
a
reactive
reactive
form
form
in
in
the
the
TypeScript.
typescript
But
but
you
you
might
might
also
also
want
want
to
to
extract
extract
the
the
data
data
from
from
this
this
form
form
in
in
the
the
TypeScript
typescript
as
as
well.
well
The
the
form
form
group
group
has
has
a
a
method
method
on
on
it
it
called
called
value
value
changes
changes
that
that
returns
returns
an
an
observable.
observable
If
if
we
we
subscribe
subscribe
to
to
that
that
observable,
observable
it's
it's
going
going
to
to
emit
emit
the
the
value
value
of
of
the
the
form
form
every
every
time
time
it
it
changes.
changes
That's
that's
how
how
I
i
was
was
able
able
to
to
console
console
log
log
every
every
value
value
change
change
in
in
the
the
demo.
demo
Now
now
we
we
need
need
to
to
connect
connect
this
this
form
form
group
group
to
to
the
the
HTML
html
and
and
bind
bind
it
it
with
with
our
our
Angular
angular
Material
material
UI
ui
components.
components
For
for
every
every
reactive
reactive
form,
form
you'll
you'll
bind
bind
this
this
form
form
group
group
attribute
attribute
to
to
the
the
form
form
you
you
defined
defined
in
in
the
the
TypeScript.
typescript
And
and
if
if
you
you
want
want
to
to
see
see
the
the
value
value
of
of
the
the
form
form
in
in
the
the
HTML,
html
you
you
can
can
just
just
call
call
my
my
form
form
value
value
and
and
then
then
use
use
the
the
JSON
json
pipe.
pipe
From
from
there,
there
we'll
we'll
add
add
a
a
material
material
form
form
field
field
and
and
an
an
HTML
html
input
input
with
with
the
the
mat
mat
input
input
directive.
directive
So
so
that's
that's
just
just
plain
plain
Angular
angular
material.
material
To
to
connect
connect
it
it
to
to
the
the
reactive
reactive
form,
form
we
we
call
call
form
form
control
control
name
name
and
and
give
give
it
it
the
the
name
name
of
of
the
the
attribute
attribute
that
that
we
we
define
define
in
in
the
the
TypeScript.
typescript
We
we
can
can
go
go
ahead
ahead
and
and
follow
follow
the
the
same
same
pattern
pattern
for
for
all
all
of
of
the
the
other
other
fields
fields
in
in
our
our
form.
form
And,
and
again,
again
the
the
only
only
special
special
thing
thing
we
we
need
need
to
to
do
do
is
is
call
call
form
form
control
control
name.
name
Everything
everything
else
else
is
is
just
just
a
a
plain
plain
Angular
angular
Material
material
form.
form
The
the
one
one
thing
thing
you
you
might
might
notice
notice
about
about
forms
forms
is
is
that
that
there's
there's
a
a
lot
lot
of
of
real
real
form.
form
The
the
one
one
thing
thing
you
you
might
might
notice
notice
about
about
forms
forms
is
is
that
that
there's
there's
a
a
lot
lot
of
of
markup
markup
code
code
that
that
you
you
have
have
to
to
deal
deal
with.
with
To
to
avoid
avoid
leaving
leaving
you
you
with
with
a
a
big
big
bowl
bowl
of
of
code
code
soup.
soup
I
i
want
want
to
to
start
start
looking
looking
at
at
ways
ways
we
we
can
can
keep
keep
our
our
reactive
reactive
forms
forms
dry
dry
very
very
early
early
on.
on
The
the
second
second
demo
demo
we'll
we'll
look
look
at
at
is
is
a
a
nested
nested
form.
form
What's
what's
special
special
about
about
this
this
form
form
is
is
that
that
we
we
have
have
a
a
parent
parent
form
form
group,
group
and
and
then
then
we
we
have
have
a
a
couple
couple
of
of
nested
nested
forms
forms
inside
inside
of
of
it
it
for
for
each
each
of
of
these
these
phone
phone
numbers.
numbers
For
for
the
the
form
form
values.
values
You
you
can
can
see
see
that
that
we
we
have
have
a
a
nested
nested
object
object
inside
inside
the
the
form
form
for
for
each
each
of
of
these
these
phone
phone
numbers.
numbers
Let's
let's
take
take
a
a
look
look
at
at
how
how
we
we
can
can
use
use
nesting
nesting
to
to
keep
keep
our
our
forms
forms
organized.
organized
We
we
have
have
the
the
same
same
setup
setup
as
as
our
our
previous
previous
basic
basic
form,
form
but
but
this
this
time,
time
we'll
we'll
create
create
a
a
reusable
reusable
form
form
group
group
that
that
we
we
can
can
use
use
multiple
multiple
times
times
in
in
the
the
parent
parent
form.
form
Again,
again
we
we
call
call
form
form
builder
builder
group,
group
and
and
then
then
we'll
we'll
add
add
a
a
couple
couple
of
of
default
default
values
values
here
here
for
for
the
the
various
various
parts
parts
of
of
the
the
phone
phone
number.
number
Then
then
we'll
we'll
define
define
the
the
parent
parent
in
in
the
the
same
same
way
way
by
by
calling
calling
form
form
builder
builder
group.
group
We
we
can
can
nest
nest
the
the
schema
schema
that
that
we
we
defined
defined
for
for
phone
phone
numbers
numbers
multiple
multiple
times
times
within
within
this
this
form.
form
So
so
maybe
maybe
we
we
have
have
a
a
home
home
phone
phone
number
number
and
and
also
also
a
a
cell
cell
phone
phone
number.
number
Then
then
if
if
we
we
switch
switch
over
over
to
to
the
the
HTML,
html
the
the
initial
initial
markup
markup
is
is
exactly
exactly
the
the
same,
same
but
but
there's
there's
one
one
key
key
difference
difference
when
when
dealing
dealing
with
with
a
a
nested
nested
group.
group
Instead
instead
of
of
using
using
form
form
control
control
name,
name
We'll
we'll
set
set
up
up
a
a
div
div
and
and
pass
pass
it
it
the
the
form
form
control
control
group
group
name.
name
This
this
will
will
be
be
our
our
cell
cell
phone
phone
group.
group
Then
then
inside
inside
the
the
context
context
of
of
cell
cell
phone,
phone
we
we
can
can
start
start
adding
adding
our
our
inputs,
inputs
which
which
will
will
take
take
the
the
form
form
control
control
name.
name
So
so
we
we
can
can
control
control
the
the
cell
cell
phone
phone
that
that
way,
way
and
and
then
then
we
we
can
can
do
do
the
the
same
same
thing
thing
for
for
the
the
home
home
phone
phone
as
as
well.
well
So
so
that
that
works
works
okay
okay
if
if
you
you
have
have
2
2
phone
phone
numbers,
numbers
but
but
what
what
if
if
the
the
user
user
can
can
dynamically
dynamically
add
add
as
as
many
many
phone
phone
numbers
numbers
as
as
they
they
want?
want
Using
using
this
this
nested
nested
form
form
technique
technique
week
week
with
with
10
10
phone
phone
numbers
numbers
wouldn't
wouldn't
be
be
maintainable
maintainable
at
at
all.
all
In
in
the
the
next
next
demo,
demo
we're
we're
going
going
to
to
look
look
at
at
form
form
array,
array
which
which
allows
allows
us
us
to
to
dynamically
dynamically
add
add
fields
fields
to
to
the
the
form.
form
Instead
instead
of
of
hard
hard
coding
coding
the
the
form
form
markup,
markup
we'll
we'll
just
just
add
add
a
a
button
button
here
here
that
that
allows
allows
the
the
user
user
to
to
add
add
as
as
many
many
phone
phone
numbers
numbers
as
as
they
they
want,
want
and
and
it
it
will
will
add
add
a
a
new
new
field
field
for
for
each
each
one
one
to
to
our
our
reactive
reactive
form.
form
You'll
you'll
notice
notice
that
that
instead
instead
of
of
a
a
nested
nested
object,
object
we
we
now
now
have
have
a
a
nested
nested
array
array
of
of
objects.
objects
And
and
because
because
every
every
element
element
in
in
an
an
array
array
has
has
an
an
index,
index
We
we
can
can
allow
allow
the
the
user
user
to
to
delete
delete
any
any
phone
phone
numbers
numbers
that
that
they've
they've
already
already
added
added
to
to
the
the
form.
form
The
the
initial
initial
form
form
setup
setup
is
is
very
very
similar,
similar
but
but
we
we
also
also
need
need
to
to
import
import
form
form
array
array
from
from
Angular
angular
forms.
forms
From
from
there,
there
we
we
can
can
set
set
up
up
a
a
phone's
phone's
property
property
on
on
the
the
form.
form
And
and
instead
instead
of
of
making
making
this
this
a
a
nested
nested
form,
form
it'll
it'll
be
be
a
a
form
form
array
array
that
that
just
just
starts
starts
out
out
with
with
an
an
empty
empty
array.
array
Then
then
the
the
next
next
thing
thing
we
we
wanna
wanna
do
do
is
is
set
set
up
up
a
a
getter
getter
to
to
retrieve
retrieve
the
the
phones
phones
from
from
the
the
form.
form
This
this
is
is
technically
technically
optional,
optional
but
but
getters
getters
will
will
make
make
your
your
life
life
a
a
lot
lot
easier
easier
when
when
working
working
with
with
reactive
reactive
forms
forms
as
as
we'll
we'll
see
see
here
here
in
in
the
the
upcoming
upcoming
demos.
demos
We
we
can
can
have
have
this
this
method
method
return
return
the
the
phones
phones
from
from
the
the
form,
form
and
and
we'll
we'll
make
make
sure
sure
to
to
return
return
that
that
as
as
a
a
form
form
array.
array
Then
then
the
the
next
next
thing
thing
we
we
need
need
to
to
do
do
is
is
set
set
up
up
a
a
function
function
that
that
will
will
run
run
every
every
time
time
a
a
button
button
is
is
clicked
clicked
to
to
add
add
a
a
new
new
field
field
to
to
the
the
form.
form
Let's
let's
call
call
this
this
the
the
add
add
phone
phone
method,
method
and
and
and
and
we'll
we'll
first
first
set
set
up
up
a
a
variable
variable
that
that
defines
defines
our
our
form
form
builder
builder
group.
group
Then
then
we
we
can
can
use
use
the
the
getter
getter
to
to
return
return
the
the
form
form
array
array
from
from
the
the
reactive
reactive
form,
form
and
and
we'll
we'll
call
call
push
push
on
on
it
it
with
with
this
this
new
new
form
form
group.
group
That
that
handle
handle
is
is
adding
adding
a
a
form
form
group.
group
Deleting
deleting
a
a
form
form
field
field
is
is
even
even
easier.
easier
When
when
we
we
loop
loop
over
over
them,
them
we'll
we'll
be
be
able
able
to
to
get
get
the
the
index.
index
Then
then
we
we
can
can
simply
simply
call
call
form
form
array
array
remove
remove
at
at
this
this
index,
index
and
and
that
that
removes
removes
it
it
from
from
the
the
reactive
reactive
form.
form
The
the
HTML
html
markup
markup
is
is
going
going
to
to
start
start
out
out
exactly
exactly
the
the
same
same
as
as
before.
before
But
but
now
now
that
that
we
we
have
have
an
an
array,
array
we're
we're
going
going
to
to
call
call
form
form
array
array
name
name
with
with
that
that
phone's
phone's
property.
property
Then
then
because
because
we're
we're
dealing
dealing
with
with
an
an
array,
array
we're
we're
going
going
to
to
need
need
to
to
loop
loop
over
over
it.
it
So
so
I'll
i'll
say
say
let
let
phone
phone
of
of
phone
phone
forms
forms
controls.
controls
And
and
while
while
performing
performing
this
this
loop,
loop
we
we
also
also
want
want
to
to
keep
keep
track
track
of
of
the
the
index,
index
which
which
we
we
can
can
do
do
with
with
let
let
I
i
equals
equals
index.
index
Now
now
each
each
item
item
in
in
this
this
loop
loop
is
is
going
going
to
to
be
be
a
a
form
form
group.
group
So
so
we
we
need
need
to
to
pass
pass
the
the
form
form
group
group
name,
name
which
which
is
is
just
just
the
the
index
index
when
when
dealing
dealing
with
with
a
a
form
form
group
group
array.
array
Now
now
we
we
can
can
set
set
up
up
the
the
form
form
fields
fields
just
just
like
like
we've
we've
done
done
in
in
all
all
the
the
previous
previous
examples,
examples
passing
passing
it
it
the
the
form
form
control
control
name.
name
The
the
main
main
difference
difference
is
is
that
that
we
we
now
now
need
need
to
to
populate
populate
this
this
array
array
with
with
some
some
items,
items
which
which
we'll
we'll
do
do
on
on
a
a
button
button
click.
click
So
so
we
we
can
can
set
set
up
up
a
a
material
material
button
button
down
down
here,
here
then
then
we'll
we'll
run
run
our
our
add
add
phone
phone
event
event
handler
handler
when
when
this
this
button
button
is
is
clicked.
clicked
So
so
that
that
button
button
lives
lives
outside
outside
of
of
the
the
loop,
loop
but
but
then
then
to
to
delete
delete
an
an
item
item
we
we
want
want
to
to
go
go
back
back
inside
inside
of
of
our
our
for
for
loop
loop
and
and
add
add
the
the
delete
delete
method
method
to
to
a
a
button
button
as
as
well.
well
So
so
make
make
sure
sure
you're
you're
inside
inside
of
of
ng
ng
4,
4
and
and
then
then
add
add
your
your
button
button
inside
inside
of
of
there.
there
And
and
this
this
time
time
bind
bind
it
it
to
to
the
the
delete
delete
phone
phone
method
method
and
and
pass
pass
it
it
the
the
index
index
as
as
an
an
argument.
argument
Now
now
we
we
know
know
how
how
to
to
build
build
large
large
dynamic
dynamic
forms,
forms
but
but
we're
we're
going
going
to
to
need
need
to
to
validate
validate
the
the
user
user
input
input
into
into
these
these
forms.
forms
The
the
one
one
thing
thing
I
i
haven't
haven't
shown
shown
you
you
yet
yet
is
is
that
that
the
the
reactive
reactive
form
form
has
has
a
a
whole
whole
bunch
bunch
of
of
different
different
states
states
that
that
it
it
can
can
be
be
in.
in
For
for
example,
example
it
it
can
can
be
be
valid
valid
if
if
it
it
is
is
passing
passing
all
all
validation
validation
rules.
rules
It's
it's
considered
considered
dirty
dirty
if
if
the
the
user
user
has
has
typed
typed
into
into
it.
it
It's
it's
considered
considered
touched
touched
if
if
the
the
user
user
has
has
entered
entered
a
a
form
form
field
field
and
and
then
then
left
left
it.
it
And
and
all
all
of
of
these
these
different
different
states
states
can
can
be
be
applied
applied
to
to
the
the
entire
entire
form
form
group
group
as
as
a
a
whole,
whole
or
or
they
they
can
can
be
be
used
used
for
for
each
each
individual
individual
control
control
inside
inside
of
of
the
the
form.
form
And
and
Angular
angular
will
will
apply
apply
a
a
CSS
css
class
class
for
for
each
each
one
one
of
of
these
these
states
states
to
to
the
the
form
form
so
so
you
you
can
can
use
use
it
it
to
to
control
control
the
the
styling
styling
based
based
on
on
the
the
state
state
that
that
the
the
form
form
is
is
in.
in
Fortunately,
fortunately
Angular
angular
Material
material
does
does
most
most
of
of
this
this
for
for
us
us
right
right
out
out
of
of
the
the
box.
box
As
as
you
you
can
can
see
see
here,
here
if
if
we
we
don't
don't
apply
apply
a
a
valid
valid
email,
email
it's
it's
going
going
to
to
give
give
us
us
this
this
message
message
that
that
says
says
your
your
email
email
does
does
not
not
look
look
right.
right
But
but
as
as
soon
soon
as
as
we
we
enter
enter
a
a
valid
valid
email,
email
that
that
error
error
message
message
goes
goes
away.
away
We
we
can
can
also
also
show
show
different
different
messages
messages
based
based
on
on
the
the
type
type
of
of
error
error
that's
that's
received.
received
For
for
example,
example
we
we
might
might
say
say
5
5
is
is
too
too
young
young
to
to
use
use
this
this
app,
app
while
while
99
99
is
is
too
too
old
old
to
to
use
use
this
this
app.
app
And
and
then
then
you'll
you'll
also
also
notice
notice
that
that
we
we
have
have
a
a
submit
submit
button
button
down
down
here
here
at
at
the
the
bottom.
bottom
That
that
button's
button's
disabled
disabled
until
until
the
the
form
form
is
is
completely
completely
valid.
valid
That's
that's
a
a
very
very
important
important
technique
technique
because
because
it
it
often
often
prevents
prevents
the
the
user
user
from
from
submitting
submitting
bad
bad
data
data
to
to
your
your
back
back
end
end
database.
database
Let's
let's
go
go
into
into
the
the
TypeScript,
typescript
and
and
we'll
we'll
import
import
validators
validators
from
from
Angular
angular
forms.
forms
Angular
angular
comes
comes
with
with
a
a
bunch
bunch
of
of
built
built
in
in
validators
validators
that
that
will
will
cover
cover
90%
90%
of
of
your
your
validation
validation
use
use
cases.
cases
For
for
each
each
form
form
property.
property
We'll
we'll
set
set
up
up
the
the
default
default
value,
value
and
and
then
then
as
as
the
the
second
second
item
item
in
in
that
that
array,
array
we'll
we'll
pass
pass
another
another
array
array
with
with
a
a
series
series
of
of
validators.
validators
I'd
i'd
like
like
to
to
point
point
out
out
that
that
you
you
can
can
pass
pass
in
in
another
another
array
array
after
after
this
this
with
with
asynchronous
asynchronous
validators,
validators
but
but
that's
that's
a
a
topic
topic
for
for
another
another
video.
video
For
for
right
right
now,
now
we
we
just
just
want
want
to
to
synchronously
synchronously
validate
validate
that
that
our
our
email
email
is
is
required
required
and
and
that
that
it's
it's
a
a
proper
proper
email
email
format.
format
Then
then
we
we
also
also
want
want
to
to
validate
validate
that
that
our
our
password's
password's
required,
required
and
and
we
we
can
can
also
also
pass
pass
in
in
a
a
regular
regular
expression
expression
here
here
to
to
make
make
sure
sure
that
that
that
that
password
password
meets
meets
a
a
certain
certain
requirement.
requirement
For
for
example,
example
we
we
want
want
to
to
have
have
at
at
least
least
one
one
letter
letter
and
and
one
one
number
number
in
in
the
the
password
password
string.
string
Then
then
when
when
validating
validating
numeric
numeric
values,
values
we
we
can
can
look
look
at
at
the
the
minimum
minimum
and
and
maximum
maximum
value,
value
which
which
we
we
can
can
use
use
to
to
set
set
up
up
an
an
age
age
range
range
for
for
the
the
validation.
validation
It
it
shouldn't
shouldn't
be
be
confused
confused
with
with
min
min
length.
length
Min
min
length
length
is
is
for
for
strings
strings
that
that
will
will
validate
validate
how
how
long
long
a
a
string
string
is
is
or
or
how
how
many
many
characters
characters
are
are
in
in
that
that
string.
string
For
for
numeric
numeric
values.
values
You
you
wanna
wanna
use
use
min
min
and
and
max.
max
So
so
we'll
we'll
say
say
the
the
minimum
minimum
age
age
is
is
18
18
and
and
the
the
maximum
maximum
age
age
is
is
65.
65
And
and
we
we
also
also
have
have
a
a
checkbox
checkbox
in
in
this
this
form.
form
So
so
if
if
we
we
want
want
to
to
verify
verify
that
that
that
that
checkbox
checkbox
is
is
checked,
checked
we
we
can
can
validate
validate
that
that
it
it
is
is
required
required
and
and
the
the
value
value
is
is
true.
true
Now
now
a
a
quick
quick
pro
pro
tip
tip
when
when
working
working
with
with
validations
validations
is
is
that
that
you
you
wanna
wanna
set
set
up
up
a
a
whole
whole
bunch
bunch
of
of
getters
getters
for
for
the
the
various
various
fields
fields
in
in
your
your
form.
form
This
this
will
will
just
just
make
make
your
your
HTML
html
way
way
cleaner
cleaner
as
as
you're
you're
setting
setting
up
up
logic
logic
in
in
there
there
to
to
show
show
different
different
error
error
messages
messages
for
for
different
different
fields.
fields
Now
now
if
if
we
we
jump
jump
over
over
to
to
the
the
HTML,
html
we
we
can
can
use
use
the
the
material
material
error
error
component
component
along
along
with
with
n
n
g
g
f
f
to
to
conditionally
conditionally
show
show
error
error
messages.
messages
Because
because
we
we
set
set
up
up
that
that
getter.
getter
We
we
can
can
just
just
say
say
n
n
g
g
f
f
email
email
is
is
invalid.
invalid
And
and
if
if
the
the
email
email
has
has
been
been
touched,
touched
then
then
we
we
want
want
to
to
show
show
this
this
error
error
message.
message
In
in
other
other
words,
words
if
if
the
the
user
user
tried
tried
to
to
enter
enter
an
an
email
email
and
and
it
it
wasn't
wasn't
correct,
correct
we
we
want
want
to
to
notify
notify
them
them
that
that
they
they
need
need
to
to
correct
correct
that.
that
Then
then
another
another
cool
cool
thing
thing
we
we
can
can
do
do
with
with
Angular
angular
Material
material
is
is
show
show
hints
hints
for
for
more
more
complex
complex
values.
values
For
for
example,
example
for
for
our
our
password,
password
we
we
want
want
to
to
give
give
them
them
a
a
hint
hint
that
that
it
it
requires
requires
one
one
letter
letter
and
and
one
one
number.
number
Then
then
if
if
they
they
still
still
enter
enter
it
it
wrong,
wrong
we
we
can
can
say
say
your
your
password
password
sucks
sucks
with
with
a
a
validation
validation
error.
error
So
so
that's
that's
pretty
pretty
cool
cool
for
for
just
just
showing
showing
error
error
messages
messages
when
when
we
we
know
know
the
the
entire
entire
form
form
value
value
as
as
incorrect,
incorrect
but
but
we
we
have
have
multiple
multiple
validators
validators
for
for
our
our
age
age
field.
field
So
so
we
we
might
might
wanna
wanna
show
show
a
a
different
different
error
error
message
message
based
based
on
on
the
the
type
type
of
of
validation
validation
error.
error
For
for
example,
example
we
we
have
have
a
a
minimum
minimum
age
age
error.
error
And
and
if
if
we
we
get
get
that
that
error,
error
we
we
want
want
to
to
show
show
a
a
different
different
error
error
message
message
than
than
if
if
it's
it's
the
the
max
max
age.
age
So
so
if
if
the
the
user
user
enters
enters
an
an
age
age
that's
that's
less
less
than
than
18,
18
then
then
we're
we're
going
going
to
to
show
show
this
this
message
message
that
that
says
says
your
your
actual
actual
age
age
is
is
too
too
young
young
to
to
use
use
this
this
app.
app
Then
then
we
we
can
can
follow
follow
the
the
exact
exact
same
same
process
process
for
for
the
the
max
max
age
age
error,
error
but
but
just
just
change
change
some
some
of
of
the
the
details.
details
If
if
you
you
have
have
a
a
ton
ton
of
of
error
error
messages
messages
like
like
this,
this
you
you
might
might
want
want
to
to
map
map
them
them
to
to
an
an
object
object
in
in
the
the
TypeScript.
typescript
One
one
of
of
the
the
nice
nice
things
things
about
about
reactive
reactive
forms
forms
is
is
that
that
you
you
can
can
handle
handle
some
some
of
of
the
the
logic
logic
in
in
the
the
HTML
html
and
and
some
some
of
of
the
the
logic
logic
in
in
the
the
TypeScript
typescript
depending
depending
on
on
your
your
use
use
case.
case
Then
then
the
the
last
last
thing
thing
we'll
we'll
look
look
at
at
is
is
how
how
to
to
disable
disable
the
the
submit
submit
button.
button
For
for
that,
that
we
we
can
can
simply
simply
bind
bind
the
the
disabled
disabled
attribute
attribute
to
to
the
the
form
form
invalid
invalid
state
state
on
on
the
the
reactive
reactive
form.
form
So
so
that's
that's
super
super
easy
easy
and
and
something
something
you'll
you'll
probably
probably
do
do
on
on
every
every
single
single
reactive
reactive
form
form
that
that
you
you
build.
build
We
we
finally
finally
reached
reached
the
the
5th
5th
and
and
final
final
demo,
demo
which
which
is
is
how
how
to
to
submit
submit
a
a
form
form
to
to
a
a
back
back
end
end
database.
database
And
and
naturally,
naturally
we'll
we'll
use
use
Cloud
cloud
Firestore
firestore
to
to
do
do
that.
that
So
so
let's
let's
take
take
everything
everything
we've
we've
learned
learned
and
and
just
just
build
build
a
a
simple
simple
contact
contact
form
form
like
like
you
you
would
would
find
find
on
on
any
any
website.
website
We
we
will
will
validate
validate
it.
it
And
and
then
then
after
after
we
we
know
know
it's
it's
been
been
saved
saved
in
in
the
the
database,
database
we'll
we'll
show
show
a
a
success
success
message
message
saying
saying
that
that
we
we
received
received
your
your
submission.
submission
If
if
we
we
go
go
into
into
the
the
Firebase
firebase
console,
console
we
we
should
should
be
be
able
able
to
to
see
see
via
via
data
data
that
that
we
we
entered
entered
in
in
the
the
reactive
reactive
form
form
saved
saved
to
to
our
our
back
back
end
end
database.
database
This
this
next
next
section
section
assumes
assumes
that
that
you
you
have
have
AngularFire
angularfire
2
2
install
install
along
along
with
with
a
a
Firebase
firebase
project,
project
but
but
you
you
can
can
follow
follow
the
the
same
same
principles
principles
for
for
any
any
back
back
end.
end
So
so
we
we
have
have
a
a
basic
basic
reactive
reactive
form
form
following
following
the
the
principles
principles
that
that
we've
we've
already
already
covered.
covered
What
what
we'll
we'll
do
do
now
now
is
is
import
import
our
our
Angular
angular
Firestore
firestore
database
database
as
as
well
well
as
as
the
the
tap
tap
and
and
first
first
operators
operators
from
from
RxJS.
rxjs
The
the
form
form
submission
submission
is
is
asynchronous,
asynchronous
so
so
we're
we're
gonna
gonna
have
have
a
a
couple
couple
of
of
different
different
state
state
items
items
here,
here
loading
loading
and
and
success,
success
which
which
will
will
both
both
start
start
off
off
as
as
false.
false
The
the
next
next
thing
thing
we
we
need
need
to
to
do
do
is
is
create
create
an
an
event
event
handler
handler
for
for
when
when
the
the
form
form
is
is
submitted.
submitted
This
this
method
method
will
will
be
be
triggered
triggered
when
when
the
the
user
user
clicks
clicks
the
the
submit
submit
button
button
on
on
the
the
form.
form
The
the
first
first
thing
thing
we'll
we'll
do
do
is
is
set
set
the
the
loading
loading
state
state
to
to
true.
true
Then
then
we'll
we'll
grab
grab
the
the
current
current
value
value
from
from
the
the
reactive
reactive
form.
form
And
and
we
we
do
do
that
that
by
by
calling
calling
my
my
form
form
dot
dot
value.
value
Then
then
I
i
will
will
set
set
up
up
a
a
try
try
catch
catch
block
block
here
here
so
so
we
we
can
can
catch
catch
any
any
errors
errors
that
that
might
might
have
have
occurred
occurred
on
on
the
the
back
back
end.
end
And
and
then
then
we'll
we'll
await
await
the
the
Angular
angular
Firestore
firestore
collection,
collection
which
which
we'll
we'll
call
call
contacts
contacts
to
to
add
add
this
this
form
form
value
value
to
to
the
the
database.
database
After
after
we've
we've
awaited
awaited
that
that
operation
operation
to
to
happen
happen
successfully,
successfully
then
then
we'll
we'll
set
set
the
the
success
success
state
state
to
to
true.
true
But
but
if
if
there's
there's
any
any
errors,
errors
then
then
we'll
we'll
just
just
go
go
ahead
ahead
and
and
log
log
those
those
to
to
the
the
console.
console
Then
then
after
after
that
that
happens,
happens
we'll
we'll
set
set
the
the
loading
loading
state
state
back
back
to
to
false.
false
Then
then
there's
there's
really
really
not
not
a
a
whole
whole
lot
lot
we
we
need
need
to
to
change
change
to
to
the
the
markup.
markup
We
we
want
want
to
to
hide
hide
the
the
form
form
once
once
it's
it's
been
been
successfully
successfully
submitted,
submitted
which
which
we
we
can
can
do
do
by
by
binding
binding
the
the
hidden
hidden
attribute
attribute
to
to
the
the
success
success
state.
state
But
but
the
the
most
most
important
important
part
part
is
is
that
that
we
we
listen
listen
to
to
this
this
ng
ng
submit
submit
event,
event
then
then
run
run
our
our
submit
submit
handler
handler
method,
method
which
which
will
will
send
send
the
the
data
data
to
to
the
the
database.
database
Then
then
as
as
a
a
final
final
touch
touch
down
down
here
here
at
at
the
the
bottom,
bottom
we'll
we'll
add
add
a
a
success
success
notification
notification
that
that
lets
lets
the
the
user
user
know
know
that
that
their
their
data
data
has
has
been
been
saved
saved
in
in
the
the
back
back
then.
then
So
so
hopefully,
hopefully
that
that
gives
gives
you
you
a
a
good
good
toolset
toolset
to
to
build
build
full
full
stack
stack
reactive
reactive
forms
forms
in
in
Angular
angular
6.
6
I'm
i'm
gonna
gonna
go
go
ahead
ahead
and
and
wrap
wrap
things
things
up
up
there.
there
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
scribe.
scribe
And
and
if
if
you're
you're
ready
ready
to
to
build
build
more
more
advanced
advanced
features
features
with
with
Angular
angular
forms
forms
and
and
Firebase,
firebase
consider
consider
becoming
becoming
a
a
pro
pro
member
member
at
at
angularfirebase.com.
angularfirebase.com
You'll
you'll
get
get
access
access
to
to
new
new
pro
pro
videos
videos
every
every
week,
week
plus
plus
a
a
whole
whole
support
support
network
network
designed
designed
to
to
help
help
you
you
get
get
your
your
app
app
into
into
production
production
faster.
faster
Thanks
thanks
for
for
watching,
watching
and
and
I'll
i'll
talk
talk
to
to
you
you
soon.
soon
success
The speakers discuss the five forms required for Angular 6, including dynamic form fields, validation, submitting form data, and creating a form builder. They also explain how to build a reactive form and connect it with the HTML, setting up a form builder service, and validating phone numbers. They also discuss setting up forms and validators, disabling submit buttons, and configuring loading states for forms. Finally, they mention a support network and offer links for further support.
Reactive Forms  - The Basics
Today, I'm going to show you everything you need to know to start using reactive forms in Angular 6 effectively. We'll do this by building 5 different forms that start at the absolute basics, then progress on the topics like dynamic form fields, validation, and submitting your form data to a back end database. Almost all apps use forms in some capacity, so understanding reactive forms is a very valuable skill to have as an Angular developer. If you're new, make sure to subscribe and grab the source code from angularfirebase.com, and I'll be giving away 3 free hats on Friday. All you have to do is leave a comment on this video. I'll be starting off here from an Angular 6 project, and the first thing I'll do is add Angular Material to this project because it has some awesome UI elements for form validation. You can install it in your project by running ng add angular slash material. Then I've already generated 5 different components that I'm going to use to demonstrate these different reactive form examples. If you don't know how to generate components with the CLI, make sure to watch episode 104 from last week. The reactive forms module isn't included by default, so we're going to import that from Angular forms. And then we have a bunch of modules that we're importing from Angular Material that handle the different form fields that we wanna use. Then all of these modules will be added down to the import section, giving us access to these various components and services. When it comes to Angular Material, there's a whole bunch of different form elements that you can use, so make sure to check out the docs and experiment with some of the examples there. The first reactive form we'll build starts with the absolute basics. Let's see how we can set up a few form controls for an email, a message, and a select field for a career. Then we'll observe the changes to the actual values being entered into this form. You'll notice that every time we enter something into this form, it updates the value object. That's because under the hood, the form is using RxJS to treat the form as a reactive real time stream. Let's go ahead and jump into the type script for this component, and we'll take a look at what we need to build the reactive form. There's really 2 things you need to know to get started, and that's form group and form builder. Form group is the actual class that we use to tie different form controls together into a single unified form. Form builder is just a service that we can use to make building forms easier. So the first thing you'll do with pretty much any reactive form is to clear the variable type to the form group, and we'll do this in every single one of the demos. The next thing we'll do is add the form builder service to the constructor of this component. Then we'll create a data model for this form during NG on a net. You can think of this as a schema for the data that holds the actual values and validation rules for the fields inside your form. We call form builder group, and then we set email, and then we can provide an empty string which defines the default value. Most forms will start off empty, but if you wanna set a default value, you can just define it here. And that's really all it takes to build a reactive form in the TypeScript. But you might also want to extract the data from this form in the TypeScript as well. The form group has a method on it called value changes that returns an observable. If we subscribe to that observable, it's going to emit the value of the form every time it changes. That's how I was able to console log every value change in the demo. Now we need to connect this form group to the HTML and bind it with our Angular Material UI components. For every reactive form, you'll bind this form group attribute to the form you defined in the TypeScript. And if you want to see the value of the form in the HTML, you can just call my form value and then use the JSON pipe. From there, we'll add a material form field and an HTML input with the mat input directive. So that's just plain Angular material. To connect it to the reactive form, we call form control name and give it the name of the attribute that we define in the TypeScript. We can go ahead and follow the same pattern for all of the other fields in our form. And, again, the only special thing we need to do is call form control name. Everything else is just a plain Angular Material form. The one thing you might notice about forms is that there's a lot of real form. The one thing you might notice about forms is that there's a lot of markup code that you have to deal with. To avoid leaving you with a big bowl of code soup. I want to start looking at ways we can keep our reactive forms dry very early on. The second demo we'll look at is a nested form. What's special about this form is that we have a parent form group, and then we have a couple of nested forms inside of it for each of these phone numbers. For the form values. You can see that we have a nested object inside the form for each of these phone numbers. Let's take a look at how we can use nesting to keep our forms organized. We have the same setup as our previous basic form, but this time, we'll create a reusable form group that we can use multiple times in the parent form. Again, we call form builder group, and then we'll add a couple of default values here for the various parts of the phone number. Then we'll define the parent in the same way by calling form builder group. We can nest the schema that we defined for phone numbers multiple times within this form. So maybe we have a home phone number and also a cell phone number. Then if we switch over to the HTML, the initial markup is exactly the same, but there's one key difference when dealing with a nested group. Instead of using form control name, We'll set up a div and pass it the form control group name. This will be our cell phone group. Then inside the context of cell phone, we can start adding our inputs, which will take the form control name. So we can control the cell phone that way, and then we can do the same thing for the home phone as well. So that works okay if you have 2 phone numbers, but what if the user can dynamically add as many phone numbers as they want? Using this nested form technique week with 10 phone numbers wouldn't be maintainable at all. In the next demo, we're going to look at form array, which allows us to dynamically add fields to the form. Instead of hard coding the form markup, we'll just add a button here that allows the user to add as many phone numbers as they want, and it will add a new field for each one to our reactive form. You'll notice that instead of a nested object, we now have a nested array of objects. And because every element in an array has an index, We can allow the user to delete any phone numbers that they've already added to the form. The initial form setup is very similar, but we also need to import form array from Angular forms. From there, we can set up a phone's property on the form. And instead of making this a nested form, it'll be a form array that just starts out with an empty array. Then the next thing we wanna do is set up a getter to retrieve the phones from the form. This is technically optional, but getters will make your life a lot easier when working with reactive forms as we'll see here in the upcoming demos. We can have this method return the phones from the form, and we'll make sure to return that as a form array. Then the next thing we need to do is set up a function that will run every time a button is clicked to add a new field to the form. Let's call this the add phone method, and and we'll first set up a variable that defines our form builder group. Then we can use the getter to return the form array from the reactive form, and we'll call push on it with this new form group. That handle is adding a form group. Deleting a form field is even easier. When we loop over them, we'll be able to get the index. Then we can simply call form array remove at this index, and that removes it from the reactive form. The HTML markup is going to start out exactly the same as before. But now that we have an array, we're going to call form array name with that phone's property. Then because we're dealing with an array, we're going to need to loop over it. So I'll say let phone of phone forms controls. And while performing this loop, we also want to keep track of the index, which we can do with let I equals index. Now each item in this loop is going to be a form group. So we need to pass the form group name, which is just the index when dealing with a form group array. Now we can set up the form fields just like we've done in all the previous examples, passing it the form control name. The main difference is that we now need to populate this array with some items, which we'll do on a button click. So we can set up a material button down here, then we'll run our add phone event handler when this button is clicked. So that button lives outside of the loop, but then to delete an item we want to go back inside of our for loop and add the delete method to a button as well. So make sure you're inside of ng 4, and then add your button inside of there. And this time bind it to the delete phone method and pass it the index as an argument. Now we know how to build large dynamic forms, but we're going to need to validate the user input into these forms. The one thing I haven't shown you yet is that the reactive form has a whole bunch of different states that it can be in. For example, it can be valid if it is passing all validation rules. It's considered dirty if the user has typed into it. It's considered touched if the user has entered a form field and then left it. And all of these different states can be applied to the entire form group as a whole, or they can be used for each individual control inside of the form. And Angular will apply a CSS class for each one of these states to the form so you can use it to control the styling based on the state that the form is in. Fortunately, Angular Material does most of this for us right out of the box. As you can see here, if we don't apply a valid email, it's going to give us this message that says your email does not look right. But as soon as we enter a valid email, that error message goes away. We can also show different messages based on the type of error that's received. For example, we might say 5 is too young to use this app, while 99 is too old to use this app. And then you'll also notice that we have a submit button down here at the bottom. That button's disabled until the form is completely valid. That's a very important technique because it often prevents the user from submitting bad data to your back end database. Let's go into the TypeScript, and we'll import validators from Angular forms. Angular comes with a bunch of built in validators that will cover 90% of your validation use cases. For each form property. We'll set up the default value, and then as the second item in that array, we'll pass another array with a series of validators. I'd like to point out that you can pass in another array after this with asynchronous validators, but that's a topic for another video. For right now, we just want to synchronously validate that our email is required and that it's a proper email format. Then we also want to validate that our password's required, and we can also pass in a regular expression here to make sure that that password meets a certain requirement. For example, we want to have at least one letter and one number in the password string. Then when validating numeric values, we can look at the minimum and maximum value, which we can use to set up an age range for the validation. It shouldn't be confused with min length. Min length is for strings that will validate how long a string is or how many characters are in that string. For numeric values. You wanna use min and max. So we'll say the minimum age is 18 and the maximum age is 65. And we also have a checkbox in this form. So if we want to verify that that checkbox is checked, we can validate that it is required and the value is true. Now a quick pro tip when working with validations is that you wanna set up a whole bunch of getters for the various fields in your form. This will just make your HTML way cleaner as you're setting up logic in there to show different error messages for different fields. Now if we jump over to the HTML, we can use the material error component along with n g f to conditionally show error messages. Because we set up that getter. We can just say n g f email is invalid. And if the email has been touched, then we want to show this error message. In other words, if the user tried to enter an email and it wasn't correct, we want to notify them that they need to correct that. Then another cool thing we can do with Angular Material is show hints for more complex values. For example, for our password, we want to give them a hint that it requires one letter and one number. Then if they still enter it wrong, we can say your password sucks with a validation error. So that's pretty cool for just showing error messages when we know the entire form value as incorrect, but we have multiple validators for our age field. So we might wanna show a different error message based on the type of validation error. For example, we have a minimum age error. And if we get that error, we want to show a different error message than if it's the max age. So if the user enters an age that's less than 18, then we're going to show this message that says your actual age is too young to use this app. Then we can follow the exact same process for the max age error, but just change some of the details. If you have a ton of error messages like this, you might want to map them to an object in the TypeScript. One of the nice things about reactive forms is that you can handle some of the logic in the HTML and some of the logic in the TypeScript depending on your use case. Then the last thing we'll look at is how to disable the submit button. For that, we can simply bind the disabled attribute to the form invalid state on the reactive form. So that's super easy and something you'll probably do on every single reactive form that you build. We finally reached the 5th and final demo, which is how to submit a form to a back end database. And naturally, we'll use Cloud Firestore to do that. So let's take everything we've learned and just build a simple contact form like you would find on any website. We will validate it. And then after we know it's been saved in the database, we'll show a success message saying that we received your submission. If we go into the Firebase console, we should be able to see via data that we entered in the reactive form saved to our back end database. This next section assumes that you have AngularFire 2 install along with a Firebase project, but you can follow the same principles for any back end. So we have a basic reactive form following the principles that we've already covered. What we'll do now is import our Angular Firestore database as well as the tap and first operators from RxJS. The form submission is asynchronous, so we're gonna have a couple of different state items here, loading and success, which will both start off as false. The next thing we need to do is create an event handler for when the form is submitted. This method will be triggered when the user clicks the submit button on the form. The first thing we'll do is set the loading state to true. Then we'll grab the current value from the reactive form. And we do that by calling my form dot value. Then I will set up a try catch block here so we can catch any errors that might have occurred on the back end. And then we'll await the Angular Firestore collection, which we'll call contacts to add this form value to the database. After we've awaited that operation to happen successfully, then we'll set the success state to true. But if there's any errors, then we'll just go ahead and log those to the console. Then after that happens, we'll set the loading state back to false. Then there's really not a whole lot we need to change to the markup. We want to hide the form once it's been successfully submitted, which we can do by binding the hidden attribute to the success state. But the most important part is that we listen to this ng submit event, then run our submit handler method, which will send the data to the database. Then as a final touch down here at the bottom, we'll add a success notification that lets the user know that their data has been saved in the back then. So hopefully, that gives you a good toolset to build full stack reactive forms in Angular 6. I'm gonna go ahead and wrap things up there. If this video helped you, please like and scribe. And if you're ready to build more advanced features with Angular forms and Firebase, consider becoming a pro member at angularfirebase.com. You'll get access to new pro videos every week, plus a whole support network designed to help you get your app into production faster. Thanks for watching, and I'll talk to you soon.
The speakers discuss the five forms required for Angular 6, including dynamic form fields, validation, submitting form data, and creating a form builder. They also explain how to build a reactive form and connect it with the HTML, setting up a form builder service, and validating phone numbers. They also discuss setting up forms and validators, disabling submit buttons, and configuring loading states for forms. Finally, they mention a support network and offer links for further support.