Handling Angular Forms Without Losing Your Sanity - Jennifer Wadella | NG-DE 2019

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right good morning everyone you excited to kick off this day and talk about angular yeah let's pump up the energy there we go all right so we're gonna be talking about handling angular forms without you losing your sanity this is near and dear to my heart it's one of my favorite things to talk about because I feel like it's an area that a lot of people struggle with a little bit about me you can follow me on twitter at like OMG at study I'm a lead angular developer at a consulting company called the tow vehicle or ghen Iser kombucha brewer and yes I love the bachelor so if you're following me on Monday or Tuesday nights us time that's when I live tweet sorry not sorry that's how I roll I'm from a place called Kansas City and I'm just gonna get this out of the way now so this is a map of the United States and that little star is where I live otherwise I'll spend the rest of the conference like trying to explain where Kansas City is the only thing you really need to remember about Kansas City is our most valuable export paul rudd yeah right so who feels like this on occasion when they're trying to implement something a little bit complicated with angular forms yeah yeah we've we've all been there right or you're like oh my gosh like it's 2019 how are we still struggling with this this is insane it shouldn't be that hard by the end of this talk I want you to feel a little bit more like this you may have seen this gift floating around the internet this is actually a Laura Wang she is a fashion designer and she's been working on launching her upcoming brand and she does this through promoting her own clothing on tik-tok she is actually not the lesbian power couple that we imagine that's her sister with her who she's constantly spotted with sporting her design so little outside angular information for you there today but she's a boss and how do we think that she maybe would approach coding reactive forms will kind of take that approach today she would of course start with the basics so it's really important to have a fundamental understanding of exactly what's going on and all the building blocks that were working with what the Euler forms no shade to the angular team sometimes the documentation isn't the clearest so I really want to help you all understand basic form elements and figure out how we can use those to start to solve really really complicated problems so you're probably familiar with the concept of template driven forms if you came from angularjs this is the way you would implement forms you would use the forms module you would use ng model to bind your inputs that's how you would do your data binding most of your logic would fall inside of the template syntax and so it was easy enough to read but could get really messy really quickly and this is typically more of an asynchronous pattern it's gonna look something like this where we are binding with the ng model to whatever are our name value is in this case for a form control where we want some sort of name so that should feel kind of familiar all right but the problem again with temperature burn forms is the second you get into kind of like a weird or complicated situation and get really gross really really quickly and it can become problematic which is why I prefer to use almost exclusively reactive forms if I have really basic scenarios if it's just like let's say a first name a last name in an email field for a user or something like that template driven forms probably going to be an appropriate approach but for everything else that starts to get a little bit complicated reactive forms are typically the way to go these are good these are gonna use the reactive forms module instead so make sure you have that updated we use the form control directive to bind to our inputs instead of using the ng model we have our logic and our controller we can move toward more towards reactive programming in this way and these are typically handled more synchronously so a form setup is gonna look something like this where we've got the form control name directive and that's how we are tying it to whatever form control that we have created and and given a name - so to understand how to solve complicated problems we really need to go again back to the basics figuring out exactly what these different pieces are of the reactive forms API and our different building blocks that we need to work with to start to build these forms so the most basic pieces are form control and this is our basic building block that's going to track the value of our our control and our validation status we've got a form group which is a way to group form controls to create an object to represent whatever data but we might be trying to submit we're going to have a form array which is an array form control so for those times that we're needing to handle dynamic amounts of form control information we can use arrays form control and form Nate control name are two different directives that we can use to tie the form elements to a form control and then you may or may not be familiar with the form builder syntax it's kind of a shorthand I like to use it a lot and I like to apply that here we're all guilty of being on Stack Overflow and copy pasting without really thinking about what we're doing and if you're not paying attention to what syntax are using you can get into some scary situations kind of quickly so first of all with the form control this is the class that represents the input element on the page with the name value that you're used to seeing any piece of information we want to collect in a form is going to be inside of a form control regardless of what kind of element we're displaying in the Dom whether it's an input a select a custom element anything like that and then we're going to use the form control directive to bind that element and tie it to its respective form control so it's going to look something like this where we're going ahead and creating our new form control and then in our template we are going to bind to it using that form control named directive okay all right the next thing we have is our form group again grouping all these form controls together so if maybe we want to submit an object that's got a name property a last name property and an email property gonna use a form group to kind of encapsulate all that together the great thing about this is it can really easily help us manage our our forms as a whole we can just do form group value to get the entire value instead of having to call and get the value individually from every form control inside of our form group so it's gonna look a little bit like this where we're creating a new form group here and then we were passing it in all of the form controls that we are interested in so this example I'm referring to with the first name we've got a form control that we're creating we might pass it an initial value we might pass it a validator we might pass it some sort of disabled status and then it's all inside of a form group and then in our template we go ahead and we use the form Group directive to bind that to whatever we have called our form and then we can use form control name and this is essentially going to act as a get it's gonna go into our form control or our form group and get the form control of first name get the form control of last name so different ways that we can go in and access our controls and understand how to manipulate them all right and then we have a form array and I feel like people are a little bit less familiar with this because a lot of times I see a lot of questions of how do I dynamically insert or remove things from my form how do I begin to manipulate that and understanding how the form array works is really really crucial form arrays are essentially like JavaScript arrays but they are meant for dealing with form controls meaning we can push things into them we can splice things out of them all sorts of things and so these can really offer us a lot of power and flexibility when starting to dynamically create forms if we've got something that's maybe user driven with how that form should be so a form array is going to look something like this where we're calling a new form array you can pass a former anything in this case I'm passing it two different form groups which then inside them contain a whole bunch of different controls you could have a form array of just form controls any sort of thing the key here is this is going to be an array and we're going to manipulate and deal with it as is a JavaScript array versus a form group is more like an object and we would manipulate it in that sense so one thing this can be a little tricky is when we're beginning to go through we need a way to iterate through however many form controls or form groups might be inside of our form array so we can simply call dot controls on our our form group that is going to give us all the controls in our user form and that might be an array that might be a group if it is an array we can then begin to iterate through all of these call each group that we have and then begin to get the properties out of that group and then finally form builder and this is my thing because my favorite thing because typing new form control a new form group new form array can get really really key tedious very quickly and I am all about saving keystrokes so it's really nice to have this kind of shorthand syntax to help us more quickly write and create forms so if you see something like this we've got this form builder class that we're going to import and then we can go ahead and call form builder group form builder dot control form builder dot array and we can populate whatever values may be so that'll save us a lot of keystrokes which I'm a big fan of so I don't want you to get thrown if you ever see the syntax around that's exactly what that means all right so we have some basic knowledge basic understanding of all these different pieces let's talk about some complicated scenarios you can start to run into and now you can really harness this reactive forms knowledge to begin to figure out exactly how to make that happen so a couple of problems that you may have run into before needing dynamic required fields and custom validation rules so you might have a piece of information a user fills that out and then you want something else to change based on the user filling out that information whether it's a new field that's required maybe something else is unrequired we've all been there dealing with this kind of stuff before it can get really quirky and then what if you have custom validation rules you not only care if it's there and if it's required but some sort of extra understanding around what a value should be how do we begin to handle that as I mentioned before with form arrays you might have run into this before where you need to dynamically create and remove form controls and form groups you've got a user and they're trying to add something to a form or take something away from a form how do you begin to manage and handle that and then what happens when you need to display one thing in an input field for instance some sort of readable text but maybe you want to submit an ID instead as your form value how do we handle that especially in a reactive form scenario so these are the kind of complicated problems we're going to be talking through and figuring out how to use all these building blocks to fix that all right so first step I need dynamic required fields and custom validation rules let's say we've got some sort of user interface like this feel free to mock my design skills there they're very peak I know but we might have something that is a basic category and when that category has a value then we want to enable something else a subcategory and then we want to require that so that is not required if category is not selected so kind of scenario where we've got multiple form control pieces that are depending on each other for values okay so the form might look something like this where I've got my input here I'm basically just iterating to display these radio buttons a bunch of different categories my form control name for this is category and then I've got my dependent subcategory field which is tied in the same way so how would I begin to understand how to get the value from category and then change the state of subcategory based on that so the first thing is we have a form group that has all these different form controls and and the two we care about are category and subcategory and so these are going to be unrequired by default and then that's what we want to go in and figure out how to change so the first thing we need to do is we need to subscribe to the changes on the field that's going to determine the other fields required nough so in this case we care about our category input we want to understand when that category has a value and then we want to make a change happen from there so this is going to subscribe to any changes that happen so anytime a user is interacting with our category control we can go ahead and get that value and begin to put in logic to determine what we want to do so the next thing we're gonna do is we are going to from our form get our subcategory this is the control we want to be in manipulating and then we can start to call different methods on our control to do what we want so in this case we know we get a change from our category and then we want to make sure that if that has a value because we can both select and unselect things if we have a value we want to go ahead and set certain validators on our subcategory control in this case just a built-in default validator of is it required if for some reason somebody removes that value from the field we want to make sure to revert and set our validators to null because we no longer care about validating that field okay all right so the other thing we need to be concerned about is the way angular works it's going to add these different classes as the value state of a form control changes so in an instance where we've got a user than manipulating a form they might have something that is required and it's going to show something in red indicating to the user that they need to fill that out if something changes we want to make sure to reset all those UI pieces and reset the form and so when we call update value in validity that's going do all that work behind the scenes to display to the user what we're trying to tell them angular has a lot of really great built-in form control mechanisms and validity mechanisms I see a lot of people sometimes rewrite it not realizing so I would encourage you to see what's already available in the angular ecosystem before rolling out to write your new one okay so we want to make sure that we're updating the value and validity reflecting to the user what's going on and then let's say okay well we've got that required now but let's say I want this user to have to have at least two subcategory selected for that to be valid how would I begin to validate or or make that happen so the cool thing is angular offers us a bunch of different ways to do validation again it's got a lot of default stuff built in for us so you shouldn't have to rewrite a whole bunch but there are scenarios where you might need to write your own validator so the first one is built-in validation and it would look something like this where we are creating a new form control and then validators will take whatever we want to pass in so required is a default one that you'll probably use quite a bit we have a whole lot of validators built in at our disposal we've got min we've got max we've got required required true meaning it's going to test for that boolean so be familiar with with what's available at your disposal the next thing we have is we have pattern validation so let's say you're having to make sure it's a valid email or a phone number and I know you all love reg X's right no you're like Jennifer no I don't want to go down this path so this is how you do that you can call validators that pattern and pass in whatever you want I like to take this approach because I know that not everybody is that excited about reg X's and they see that and they start to like cry and Shake inside so I like to name mine so somebody can know that okay this is what that's checking for and then just pass in that variable let's that's a little timid I do to make people and my team hate me a little bit less so we can do a pattern validation we can use required built-in validators and then finally we can do function validation and this is where we have a little bit more complex logic so in the situation I was talking about before let's say I'm validating an array and I want to make sure that that array has at least two items in it I can go ahead and I can build out this own validator I am going to pass in the form control which is the thing that I am attaching my validator to return whatever my logic may be and then I can pass that validator I've created in just the same as I would pass in any of the built-in validators cool so if we then go back to our original form control where we've got our category when it changes our subcategory is then required and then we want our subcategory not only to be required but also to have a minimum requirement of two items we can do something like this where I am creating my validator function and then when this changes I am passing in the required validators as well as my my min validator I don't necessarily have to do the required one in this instance because it's gonna get checked by the min validator but that's an example of how you can pass in multiple Valladares to a form control cool alright next I need to dynamically create and remove form controls and form groups so when you are having user input where you need to change a form based on what they're looking for so it might be something like this let's say I have a recipe application and it might take ingredients an ingredient could have a name and it could have an amount so I recipe might have five ingredients my recipe might have twenty ingredients or maybe I think it has twenty but I don't actually want salt in that so I want to remove it so how do we manipulate and create this dynamic form where I can add and remove these these form groups of controls as I as I need so the first thing to understand is we can call form control can be called as a form array so if we are going to be doing something dynamically where we know we're gonna be inserting or removing a bunch of different things we want to go ahead and put that in an array so here my my ingredients is the form control we're going to be working with which is going to be a form array it's important to know that the form array has a couple built-in methods and these are what we need to be using to manipulate our our forms for the proper behavior we have an input method that is going to take two parameters the index where we want to insert the form control so dealing with an array telling it where inside of that array we want to insert it and what form control we want in at that point and then there is a remove that method which is just going to take the index of the control that we want to remove so figuring out where that control that we want removed is inside of that list using the the index of that it to use and remove it so let's start down here we have this user form and I have a form control of users which is a form array and inside here I've got a group it's gonna have a first name a last name in an email and I'm I have two instances of this form control group so if you've ever done like adding somebody to a slack channel and you're trying to add multiple people at once kind of that that same thing mentality wise so rendering that in my markup I've got my user form here and I am iterating through my users controls so users a form control controls inside of there is going to be that array that I'm passing in each item in that array is a form group that is going to have a form control a first name last name and email so that's how I begin to manipulate through there a couple things going on here I might have a button tied and I'm setting my index to be I as I'm iterating through here so I know where that is in my array if I would want to remove one of these fields and I can call a remove form control function that I've written with whatever that index is that function will look something like this where I am getting the index I am getting my array of form controls and then on that array I am calling remove at and whatever index I'm dealing with and then I might have an ADD control button so I've gotten a method written there where I am getting my array and I want to get the the length of the array maybe I want to make sure I'm inserting it at the very end and then I am creating a new form group and I'm passing in whatever it values I want and then I'm calling insert where I'm inserting at wherever that index is and this new form group that I have created and so this is how we can start to build dynamic forms that we can have a user interact with and remove and add to form controls so in my example where I was showing the different ingredients this is kind of what that code would look like and different form where I'm getting my form array I'm creating a new form group of my ingredients I care about name and amount and then I'm inserting that or I am removing from my array whatever ingredient I no longer care about all right and so our final problem and this is my favorite one to talk about I need to display one thing in an input field for a user but I need to submit something else I am a very common scenario you might have run into this with is dealing with type-a heads and you might be typing something and populating some sort of name or value but you want to submit an ID and how do you do that in a reactive form sense where there's almost like this the stricter more coupled binding so let's say I have created the this really custom UI piece where I have some sort of star rating system and I want to submit a value of 0 through 5 or 0 through 4 based on whatever that star rating is how do I go between a user interacting with this piece and submitting whatever value without getting into outputting and inputting events and really bad event emitter soup this is where the control value access our interface comes in and this is essentially going to allow us to create components that will act as a form control and emit the value we want so control value access or interface is an interface and typescript which means it has a couple different methods that we absolutely have to implement for this form control to work because we want it to act as a native form control and have all the validation and everything built-in under the hood form control or control value access there's kind of like taking your own component and like almost tricking it and making it behave like something else like an actual real form control so really exciting really powerful tool that not a lot of people know about but that will solve pretty much any form problem you can run into outside of everything I've described so far ok so if we were to create a new component we might call it my sweet component and then we would just insert it in our markup like normal and then we can go ahead and still use our form control name directive on it to bind whatever form control is to that component and this is the same as using this form control directive and iterating through the controls and passing in whatever control you're looking for so we might have some star markup so this is just an SVG that is creating that star I've got some functionality going on here whether I want to that started to be disabled or not and then I have this click function that when I click on a star I want to go ahead and actually set that rating so how do we begin to wire that up to use the control value access or interface to make sure that whatever star value I'm submitting is getting back to my form we're gonna do a couple things I mentioned that we have to implement several methods because it's an interface so the first one is the right value method and this method is going to be called any time a form control is interacted with and gets a new value written so if we call set value on our form control in the parent form this function is going to get executed inside of our custom component we also have a register on change function in a register on touch function which we need to call to let the form know what we're doing and what we're manipulating so that means when I click on a star I want to call my register on change function to let the form control know that this has changed in past pass at a value we also have the register on touch function this is how we get that blur functionality so if you've ever interacted with a field and left it and then you've seen some sort of validation status on it we need to let the form control know when it's been interacted with so then we can display relevant information to the user we have a fourth optional method which is set disabled State this does not need to be implemented but it's really really helpful so if you have a disabled form control you need some way to harness that and show something in the UI you will this method will be called anytime that that disabled status changes with whatever the status is and then you can use that for whatever UI purposes you need to show that it isn't a disabled State so in this case if we go back again we have this click function where we're calling set rating and whatever that star value is okay so inside of our component where we have implemented the control value accessor on that function we might do some other stuff to display the UI for instance I'm setting a rating text to let somebody know what that might look like and then I am calling on changed with whatever that new value is which is going to emit to the form control let it know that the has changed and then I'm also gonna call untouched just to let it know that it's been interacted with so let's say I touched it didn't submit a value we could use validation built in to kind of show an error class and she touched if you're making a user know that they've touched a field and want to show that it's valid so to kind of recap what we talked about with solving these complicated problems we talked about the reactive form building block so having a really deep and thorough understanding of these building blocks and the different methods on them is really really important if you want to go dig through the docks there's abstract form control class is what everything is based off of so pretty much everything implements that that class and you can go and read through the different methods available and that that'll allow you to control status it'll let you just set the value it'll let you understand the validity set validators on it all those different methods and being really familiar with those will really help you build reactive forms I don't see a lot of instances where you need to put layers of abstraction or other libraries to handle form elements if you have a good understanding of these basics then we have the form group which is a way to group form controls into an object we can iterate into that just like a regular object and get whatever form controls we need we have a form array which acts as an array of form groups or form controls that will allow us to iterate through and map those out to do whatever we need that has the two methods the insert and the remove methods that allow us to insert and remove from that form array we talked about subscribing to value changes so a lot of times you're wanting to react to something that happens and so understanding how to subscribe to those form value changes and make everything happen in the UI that you need to to show whatever that that changes is really important we talked about using different validators exploring the built-in ones min/max required we talked about pattern validation so in the cases that you need to use a regex and pass that and use as a valid air and then we talked about function validation if we need to build custom functions to do some sort of validation we looked at iterating through controls how we drill into a form array into its controls and then begin to map through that to display what we in the UI get the index of that if we're needing to remove a we talked about adding and removing to from form arrays using those different methods and utilizing the control value access or interface I also blog about this stuff a lot I know 30 minutes it's not a lot of time for this advanced of content but tons of great information out there so I would really encourage you to really deeply explore all these different topics to really master forms and most importantly learn to embrace your inner Laura and just be a badass when it comes to dealing with angular forms there's really not a lot of complicated scenarios outside of this that we can't handle if we don't have a good understanding of this mm-hmm I know we are scheduled for a break in a couple minutes so if you have any questions I would love you to come talk to me during the break I want to hear all about your form problems and the issues you're dealing with and help you walk through those if you are interested in these slides where all the code snippets are available they are at 10 I can github do slash handling angular forms and for all sorts of reactive forms content or whatever I feel about blogging about angular you can check out bateau be calm slash blog where I throw up all sorts of information there that is all I have for you I hope you have a wonderful rest of your day you lovely human beings
Info
Channel: NG-DE Conference
Views: 11,233
Rating: 4.8800001 out of 5
Keywords: angular, forms, reactiveforms, angular forms, Control Value Accessor, ngde
Id: iqXiic6hE9U
Channel Id: undefined
Length: 27min 54sec (1674 seconds)
Published: Tue Sep 10 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.