Advanced Angular Forms - Free Mini-Course (Template-Driven)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone welcome my name is dimitro majenski and from this video you will learn how to start with template driven forms in angular but not just how to start this is something you can read in official angular documentation I'm going to show you also what is going on under the hood when you import forms module this video is just a tiny part of my new upcoming video course dedicated to angular forms where you will find more than seven hours of in-depth videos dedicated to tablet driven forms reactive forms and also in the end of this of the full version of this course you will be able to build your completely custom form controls like this funny rating picker or this cool drop down select component that allows user to pick some option and also it will support the multi-selection and navigation and option selection using your keyboard officially the full version of this course will be available from November 11 2022 so basically in the end of this week and if you are watching until this date you have a chance to get the full version of this course for free how to do that you will learn in the end of this video but for now enjoy this video and I hope you will learn something interesting thank you before we dive into the course and start learning angular forms and their different variations like templation or reactive forms I would like to talk with you about building blocks that are essential and common for both of them I find this lesson very important because we will be dealing with that building blocks directly or indirectly every time and it doesn't matter which type of forms we use so let's have a look at some native form control like text input what we can say about it which hypothetical properties could it have well we can say that the form control can have some value right it can be valid or invalid or it might be enabled or disabled so in short we can say that the input has some State obviously we can change the state by setting the new value we can enable or disable the control and so on to represent the control State angular uses a special abstraction that you must probably know and use and it is called form control this is just a simple JavaScript class whose responsibility is to hold the state for instance value validation status Etc its responsibility also to provide methods for the state updating and it should run validators when the value of the form control instance changes by the way because it is just a simple JavaScript class you can even import and instantiate this class without importing any angular forms model sure by itself it is quite useless but you can actually do it if you want so why do we need this abstraction well because the state of control should not depend on the concrete implementation of the control we should not directly access the input when we want to read the value of the control we want to get a value and we don't care if it is a text input or if it is a native select element or if it is some custom component and here you might think like all right you say that form control knows nothing about text inputs and other types of controls but how the form control synchronizes the value between native control and its own state well form control doesn't work alone it works intend them with value accessor it is another class that knows how to work with concrete native control API and its responsibility to perform a state synchronization between the native control like text input and the corresponding form control instance because there are many different Native controls like text input select and so on there are also many different value accessors which we'll learn in detail in the full version of this course but we are already slightly out of track so let's get back to the form controls form controls can exist Standalone but if we think about some random form we will see that it is a actually a group of different form controls right so form controls can be grouped and there is a dedicated model which describes this use case and it is called form group groups can be nested so it means the group can contain another group and so on and usually the root group is representing their final form the main responsibility of form group model is the aggregating state of form controls that belongs to this group for instance the value of the form group is an object that Aggregates all values of the form controls it contains the combination of form group and form control models is something you will be dealing with in 80 percent of cases less often you may encounter the model form array that is doing also grouping but it groups form controls in the array unlike the form group model that groups everything into the object and if you are very experienced with angular forms you can mention also the brand new form record model but from the functional point of view it is the same as form group the only difference between them is that form record brings some simplified typing definitions if you have to deal with the form group where you have to dynamically add or remove form controls that's it so basically we have the following models available in angular forms it is a form control it is a form group form record and form array what is also worth mentioning is that all those four classes directly or indirectly extend the common abstract class that is called abstract control and that's why all models have a lot of common in their public API but obviously different implementations of course so if you see in the code that some function or or validate or expects as an argument abstract control it means that you can provide any of that for classes and it will just work [Music] in this video I will start showing you how to start with template driven angular forms and explain to you what is happening under the hood when we import an appropriate angular module so let me open a component where we will be mostly working it is called template forms page as you can see the component is almost empty but if we jump to the components template template you can see that we have some HTML form nothing special actually here this form has no angular directives components handlers or anything else just a pure HTML5 form and this is how it looks in a browser pay attention that when I click the save button the page is being reloaded which is actually the default Behavior well in order to start with template driven forms in angular we have to import an appropriate model for that if you build your application with NG models you can import the forms model into the model where you are going to use its features but if you use Standalone components as I do in this course then you need to add the model to the Imports array for the component forms model is responsible exclusively for template driven forms and once I import forms module I activate this kind of angular form in this component or modern if you use them and now if I save this change and go to the browser you will not see any visual changes however if you try to click the save button one more time you can see that the page isn't being reloaded anymore so it turns out that some magic happen once we imported the forms module but what happened exactly actually this module exports some set of angular directives and some of them were automatically attached to our form now let me quickly prove my statement in the browser console I'm going to use an angular utility that is available when you run your application in development mode and this NG object provides a set of helper functions that you can use and in my case I need get directives method which as an argument expects a reference to the HTML element which you are going to inspect in our case it is a form so you can either use methods from the document object like get element by tag name and then get the reference to the form this way or you can use an element picker tool and once you pick the element the reference to the selected element will be available in a special variable in the console called dollar sign zero so now if I run this code you can see that three directives reside on this node namely in Geno validate NG control status group and NG form it happened because of imported forms model so if I remove it from Imports and run the same command again you can see that there are no directives anymore and the array is empty so let me quickly revert this stuff but how those directives were automatically applied shouldn't we add them manually in the template like that well what I have done now is so-called attribute selector for a directive but the truth is that the selector for the directive can be also the tag name or css selector and in this case the directive might be applied kind of automatically and this is exactly what happened in our scenario here you can see a source code of the NG form directive one of the directives that were applied to our form you can see this long selector that contains actually three selectors separated by a comma the last two have no impact on our particular use case but the first one is exactly the reason why the directive was automatically applied because look it says a touch that are reactive to the HTML tag form that has neither NG no form attribute nor form Group which makes our form tag a valid selector from it we can also make a conclusion that if you want to make angular ignore some particular form you can just add an attribute ngino form to the form tag and then that set of angularform directives will not be applied so the form will be kind of ignored obviously it is not what I need so I will revert it let's get back to the NG form directive source code again you can also see that the directive handles some native JavaScript events like submit and reset for the host element by the way this notation is equivalent to the host binding decorator that is most probably more familiar to you here below you can see outputs and again it is an equivalent notation to the normal component output decorator so now when the submit event happens for the form this directive reacts and handles it by doing some control synchronization emitting NG submit output passing the native event as a value and then it returns false that actually prevents page reloading but yeah all this implementation details are very interesting but we should get back to the topic while we are inside the angular source code I would suggest you also quickly have a look at the forms model itself here you can see forms model and reactive forms model that we will cover in the separate section so let's focus on the first one if you are an experienced Android developer then nothing should surprise you it is just a regular NG model that declares a set of directives assigned to the constant template driven directives and namely NG model NG model group and NG form directives are declared all of them we will cover in this section if we go back you can see also the internal forms shared model which exports a set of shared form directives those directives are common for reactive and template driven forms some of them we will use in this course and some of them are being used internally like NG control status Group by the way if you remember this directory was also the one that was attached to our form automatically so now let's quickly recap what we have learned so far in order to start using template driven forms we must import forms module this model exports some set of angular directives that are automatically applied to the form tag on the page because those directives are using the tag name selector to investigate what directives resides on the HTML element we can use the get directives method from the global NG object both reactive and template driven forms have a set of shared directives but of course there are directives that belong specifically to some certain form type I hope I was able to explain it clearly enough and you have a better understanding of what is going on under the hood [Music] forms are the way users interact with data and I think you agree with me that without data forms are kind of useless so let's create some pieces of data for this section somewhere under the core folder I create a new typescript file called user info and this file will export some interface that describes the user information namely we have to Define all the fields that are available in our form so I will add the first name field which has a type string same for the last name and so on and so forth now we would need to create an object that implements this interface so I will go to my component file and make a new property with the type user info typescript definitely complains because required properties are missing so let's Implement them cool now we would need to somehow bind this form model with the actual form in the component template in template driven forms The Binding happens by using the NG model directive we will learn more about this directive later but for now just treat this directive as a bridge between our form model and the native control which is like input in our case however it is still not enough information for angular on how to bind an appropriate form control with the corresponding field in the form data object so we have to Define it somehow explicitly but how if we look up the source code of NG model you can see that there exists an input called NG model as well and it does track a value that is bound to this directive exactly what we need actually so according to that we can use the entry model property to provide the value that needs to be bound to this particular control in such a way we have connected the form control with the corresponding field in the form data model this notation also can be shortened because when the directive property and selector have the same name then you can leave only data binding and the result will be the same because such a way you declare the angular directive on some HTML tag and at the same time you provide the value for the directive property however it would be still not enough to make it work because if we open the browser console you can see a runtime error and namely it says that we use NG model within a form tag so that's why we should also provide a name attribute or we should Define this control as a standalone about Standalone controls we will talk later in this course so let's fix it by adding the name attribute to our control so I go back to the template and add the name attribute with the value first name cool now the form group that is created for the form tag can properly work and track this control because it has a unique key and also you can notice that error inside the browser console has disappeared now let's get back and make sure that our binding is actually working so I will change the value in the form model to some string and we can see that the value was synchronized with our form control which is cool but the data can be changed also by the user so another way around and currently we have a problem with that let me quickly demonstrate it somewhere here above I will create a paragraph and here below I will print my form model data and I apply the Json pipe for some nice formatting and this is how it looks now in the browser you may notice that when I change my first name this change isn't reflected in the form model though it should be it happens because currently we have one-way data binding and our data flows from the form model to The View and our input is a part of this view that's why our changes in the input that basically happens on The View side they are not synchronized because we don't currently have any mechanism which would Implement two-way data binding and synchronize the value from the view to the model to make the two-way data binding work for the NG model you should use a construction called banana in the box and in such a way the data will be synchronized from the data model to The View and vice versa now you can see when I type in the first name field the changes are also propagated to the form model I will not be explaining in detail two-way data binding in angular and just mentioned that it is not something NG model specific and if you would like to know more about it you can have a look at the video Edition number 2 for this course but yeah let's continue and obviously we should bind the rest of the properties with corresponding controls likewise we did it for the first name so I will copy this part and apply it also for the last name of course with some small adjustments and in order to save your time I will pause the video and get back when I update all controls so welcome back I just updated all my controls and now we can go to the browser and see that everything works fine you can see I'm changing the field last name and the value is being synchronized perfectly with the form model the same works also for the nickname email control works as well so everything works just as we expected now it is time to recap what we have learned so far to bind the form data with the HTML form using template driven forms you have to use the NG model directive that works like a bridge between the native form control and your form data it helps to track and synchronize value changes and react to the controls state to achieve a two-way data binding for the control and Associated data you have to use the banana in the Box syntax and also do not forget to add attribute name to your controls because it is required for the proper work of the NG form directive [Music] so we have already learned to angular directives and deform and NG model we know what they are responsible for and now it is time to dive deeper and explore what happens under the hood and how those two directives relate to each other this video is not mandatory and you can safely skip it if you like this video is for those who really like to know a little bit more about the internal implementation of angular features but it is not mandatory for the father videos in the course so let's get started from NG model I'm going to pick the first input as a test subject and using the already familiar get directives method I get the list of all directives that reside on this node so you can see three directives the first two ones I'm going to skip because we will cover them in separate videos and let's focus on the NG model here you can see properties that should be already familiar to you the model property that keeps basically the value of the form control and here you can see the name property and it is exactly what we defined for every form control as a name property in the component template also besides those two there are a couple of other properties I would like to highlight here the first one is the control property whose value is an instance of some form control class the form control class is one of the four building blocks in angular forms and it is responsible for tracking the value and validation status for every single form control basically it represents a state of the form control right we will learn more about form control in the section about reactive forms because it in reactive forms we work with this form building blocks directly while in template driven forms they are kind of encapsulated by the directives like NG model but it allow us to build forms declarative way so far just treat the form control as a representation of the form control State and it is a single source of Truth for the mg model directive you can see here some properties of the NG model class like value valid or invalid they all are Getters that read the corresponding value from this form control that's it the following property I would like to mention is form directive and it contains the reference to the NG form where this NG model directive has been declared it needs this reference because NG model is also responsible for registering its form control instance inside the NG form directive and NG form is a kind of aggregator of all form controls declared within the form the form control registration happens inside the NGO changes lifecycle hook of NG model uh it happens by calling setup control method that eventually calls at control method and there happens already the registration of the control in the NG form using the name we provided as a key and the form control is instance as a value so if we get back to the NG form directive instance we will see the following picture the NG form has the property called form and this is an instance of form group the form group is another building block of the angular forms that we will cover more in the section about reactive forms but basically the responsibility of this glass is quite similar to form control ones it is tracking the value and validation status by but this time for their collection of form controls and for instance if at least one form controls within the group becomes invalid then the whole form group becomes invalid and the same is applicable for other four control States so this form property contains all our form controls registered by NG model directives in our form here you can see the object where the key is the name we provided for NG model and the value is the corresponding form control instance and this is the reason why that name property is required because the form group and form control extend the same abstract control they have many common properties and one of them is value but unlike the form control that stores one single value the form group has an object that contains values of all form controls and nested groups yeah we can have nested form groups but we will learn it a little bit later in this course but so far let's recap what we have learned apart from all the NG model directive is also a container and owner of their form control instance that is the smallest building block of angular forms the form control is responsible for the value tracking and validation state of an individual form control like input select Etc additionally NG model has a reference to the parent NG form directive that is basically a container for the form group instance which is grouping multiple form control instances and tracks value and validation status for the whole group of controls so the value for the form group will be an aggregation of all form controls within this group [Music] thank you if we have a look one more time at the NG model source code or documentation of this directive we can discover that it has an input called NG model options where we can path some config here you can see three options name Standalone and update on property I go back to my template and let's create an appropriate property binding for the NG model options input where we will provide a config object and let me quickly format it like that so it will be more readable for you I would suggest you get started from the name option the name is nothing else as a name we defined here and it is basically just an alternative way to provide it so instead of using the input I could provide it with the config object like that it was save and reload the page you can see that there are no errors and everything works now let's get back and talk about the update on option currently NG model modifies the model value every time we type something and it might be too frequent in some cases for instance the validators are being triggered every time the form control value changes and we might have a very expensive validator that we don't want to run so frequently because otherwise we might run into performance issues and NG model allows us to configure this strategy and explicitly tell form control on which event the value should be updated there are three available values for that change blur and submit by default the change event is being used so we saw it already in action now let's try to use the blur strategy and now you can see that the form control updates the value only when we move the focus away from this particular control in such a way triggering a Bluer JavaScript event and this is actually a widely used strategy and you can see it in many applications also you can instruct from control to update the value when the form is submitted so now the first name will change only when I press the save button triggering the submit event for the form and you may ask uh if I have dozens of NG models in my form and I want all of them to be updated on the blur event should I configure each model separately and it is a reasonable question and the solution for that is using a property NG form options that is available for the NG form directive the config for NG form options has only the update on option that might also have three possible values they are the same change blur and submit and if you define the update strategy here to blur for instance then all form controls in this form will inherit this strategy you can see now all of them change the value only on the blur event of course this Global strategy might be overridden for the single NG model by explicitly configuring the update on property in its config object so let's say if I replace here again with change then the first name will be updated every time I type something into the input but other form controls will be updated only when the blur event has been triggered so this is how the update on strategy works the last option available for NG model config is Standalone but about that we will talk in the next chapter so see you there [Music] in the previous chapter I mentioned that NG model can be Standalone so let's talk about it in more detail when the NG model is Standalone it means that it will not register itself in the apparent NG form for instance if I make it Standalone and then go to the browser and inspect the list of controls in the NG form directive you will not see the first name control because it is Standalone and it doesn't belong to this form anymore also if you have a look at the value of the form you can see that the first name key was obviously excluded as well when it could be useful well there might be a couple of scenarios when you would like to exclude some form control from the form it can be some so-called helper input which might be needed for proper work of the form but we are not interested in its value for instance you might have some autocomplete where you are interested in the selected value from the autocomplete rather than the input value itself we could have a case where we don't want to save the user's year of birth but we use this select in order to detect the user's age and show some additional form Fields depending on the user's age something like that you know so this is the first scenario the second case is when you need just a single form control in your component it might be some Global search field somewhere in the header or maybe there could be some drop down to pick the website language things like that because creating a form for that kind of control is quite obsolete so it is the perfect use case for the Standalone form control and because later in this course we would need some Standalone input like Global search so I would suggest you implement one in the header component so I go to the header component and somewhere here after links I add the input with the class Global search and placeholder Global search as well then I'm going to apply the NG model directive and I Define some search string for it we could add NG model options property and Define that it is going to be a standalone model but if you use NG model outside of the form then it will be configured as a standalone by default you should do it explicitly only if it is a part of the form so in my case I can remove it then I go to TS file and create a property search string that is an empty string by default and because we use NG model in this component I should also import the forms module let's quickly check how it looks like all right it could be better first of all we should restrict the width for the input and I think it would be nicer if we had a logo and input pushed to the edges and navigation would be in the middle so then I would go and wrap navigation links with some diff with the nav class and then in my Styles I will add style for the global search field and restrict the width for the navigation links container I applied display Flex property and for header I should apply justify content with a value space between to push logo and the search field to the edges and navigation take a center between them and the last but not least so we should we should remove Standalone property from our form like that now let's check our application and it looks definitely better alright let's quickly recap what we just learned in Standalone mode NG model doesn't register itself in the apparent form so the control will not be available in the form and form value in order to configure the NG model as Standalone you have to provide an option Standalone set to true but if you use NG model outside of the form then Standalone mode will be picked automatically Standalone form controls might be useful when you need some control to make the form properly work but you don't want this control to be a part of the form control group or if you need just one single control like a global search we just created [Music] alright we have already learned quite a lot about template driven forms we know what angular directives are responsible for this kind of form how they relate to each other which options are available to configure those directives and of course we can bind our component data to the actual form and synchronize its values in real application the interaction with the form almost always ends up with the form submission and this is exactly what we will talk about in this lesson so as you may remember the NG form directive listens for the native events submit in our form then it handles it and emits an event on submit via event emitter and this is the event we are going to listen in our form so I go to the form and add a new listener for this event and create some Handler function that will be executed once this event is triggered and let's create this Handler in our component TS file and let this Handler just going to lock some string for now if we save this change and go to the browser we can see that once I press the save button the submit event is triggered and my callback prints the string in the console but we submit forms not to print out strings in the console right we usually want to access the form values and dispatch them to the server or handle it some other way we cannot rely on the user info property because the form model should not necessarily be an object like we have now and the model doesn't care about its structure you could extract the first name for instance to separate property and provide it as a value to the corresponding NG model and it will work fine and for the rest of the values there could be the same story and it would be very very inconvenient to deal with multiple sources but we remember that NG form has a form group that basically contains all the form controls registered in this form and its values so we would need to get a reference to the NG form and read the value from there the best way to do it is to assign the instance of NG form directive to the template variable like that and now we can pass it as a argument for our callback by the way if this everything looks like magic to you then have a look at the video Edition number two for this course there I explained in detail how it works but we continue and let's adjust the Handler and Define the NG form here as a first argument now we can read the form values from the form like that so now we can go to the browser change some fields and now you can see that the form value was printed out and now you can do whatever you want with that data if you remember the NG form directive propagates the native submit event as well and if whatever reason you need it you can easily get access to it via dollar event and provide it as a second argument for the Handler so you would be able to read it here and do whatever you want with this event usually you don't need it but let it stay here as a reminder for you that it is possible of course you would like to reset the form after you submitted it about form resetting let's talk later in this course because reset is not about values resetting only it is also about the form validation status so I would suggest you cover those topics first and then we will get back to the formula setting and I will show you how to do it properly for now we could do a temporary hack and just manually update our form model and reset values like that so now if I go to the browser modify some fields and click the save button you can see that the values were reset the last thing I would like to do is to clean up my view a little bit because we can already see the form values and I don't need this printed user info anymore so I'm going to remove it also I want to remove NG form options I would like to have a default update on strategy and the same I do for NG model options so I remove it and revert back the name for this NG model like that and now we are ready to move forward all right guys I hope that even from this short like relatively short but free version of the course you could learn something new and by the way on my platform decoded front-end there are more videos from this course available for free so you can continue watching if you want just follow the link in the video description and enroll in the free version of the course and as I said if you are watching this video until November 11 2022 you have a chance to get this course I mean the full version of this course for free and this is what you have to do for that so there are basically three very simple steps the first one the very important one you have to leave comment under this video any comment doesn't matter the Second Step you have to let me know if you like this video by hitting thumbs up or thumb down if you didn't like for whatever reason and the last step it is also very important you have to share this video in any social media you like so it can be Twitter it can be LinkedIn Instagram you name it and then on November 11th it will be the live stream where I will pick at random five winners among those who left comment under this video so don't forget to do that and if you fulfill all the requirements then you will be enrolled in this in the full version of this course for free and this is basically it I wish you good luck have a great week and see you on Friday stream
Info
Channel: Decoded Frontend
Views: 24,602
Rating: undefined out of 5
Keywords: advanced angular forms, angular forms, template driven form, angular forms tutorial, angular forms reactive, angular form validation, angular forms module, angular form validation error messages, angular forms reactive vs template, angular form submit post data, angular advanced forms, template driven forms
Id: cWXhaFBGArk
Channel Id: undefined
Length: 47min 21sec (2841 seconds)
Published: Mon Nov 07 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.