Check out a free preview of the full Angular 13 Fundamentals course:
The "Form Handling" Lesson is part of the full, Angular 13 Fundamentals course featured in this preview video. Here's what you'd learn in this lesson:

Lukas walks through building out the course form, generating and importing an interface using ng commands, and attaching ngModel to an input. The effects of input properties matInput, placeholder, ngModel, name, and type are also demonstrated in this segment

Get Unlimited Access Now

Transcript from the "Form Handling" Lesson

[00:00:00]
>> In our courses component dot HTML, we are gonna come in and we are gonna start to build this out. And so what I wanna do here is attach a form and we're going to put this around because. So the one thing is with a material cart is you have your content and then you have your actions.

[00:00:28] And we're going to wrap this entire thing inside of a form. So the form body is going to go inside of the content and then the actions themselves are going to go inside the actions section of the card. And from here let's go ahead and we're going to go form equals mg form And, Let's go and just so we can see some of this in action We'll get on pre And we'll just go form, non value, JSON and I'm gonna duplicate this and we'll go valid.

[00:01:31] And I'm not quite for sure what's gonna happen because there's nothing in here, but it's a good No direct is found with export as in G form, what do you think that could be? Let me check. It's like I'm like a prophet like I'm a minor prophet like, I'm over you're saying everybody needs to be real careful.

[00:02:02] Well, there you have it. We just organize imports just because I'm obsessive compulsive, all right. Better, so make sure you import your forms module and we have a form, we don't have any input fields, it's not doing much. So let's go back into our code here and let's start to build the cell.

[00:02:41] So, I'm gonna type one of these out and then I might copy paste the rest of them or some of them, just because typing is not that interesting. I'm gonna give this a class of full width, and we're going to add an input. And from here, we're going to add in mat input here, we're going to give this a placeholder of title.

[00:03:28] And, I'm going to do something that is going to blow up, but let's do it anyways current course title, So there's a couple things that is problematic about what I've done up to this point, but YOLO let's see what's going on here. So current course that's super easy, so let me go back here Let's try this again.

[00:04:25] So, This is what happened last time, so you can do a couple things here that I think are okay. The first one is, I'm pretty sure I can put a safe navigation operator in here. And the expressions are not allowed, okay. So one of the things that I will say about angular 13 versus its predecessors is that it is a lot more strict.

[00:05:04] So, what I'm gonna do here is, they're forcing my hand to solve a problem that I was going to solve a little bit later, but I'll do it now, that, When I have a form that I'm using to either create or update something because you absolutely can use the same form.

[00:05:36] That when I have something selected something, let's say a chorus, then I bind that form to the chorus. But if it's empty, what I want is to essentially bind it to an empty course object that gets populated. So that when I save it, it just passes it down the road if you will.

[00:06:02] So, from here what I am going to do, I feel like this is a really good time to generate an interface for this. So, Fortunately this is from previously when I did this, so NGG interface common models course. And so anytime this is generally one of the first things I do when I'm building something out is I will actually build out the interfaces first.

[00:06:38] And then everything else is able to be kind of inferred or generated off of that, so let's just double check. Looks good, and so just let it be known for the record that in this particular module, I generated an interface so that we could see it. So now, we'll go to common here and we just look at this real quick, id, title, description, percent, complete.

[00:07:17] So, Id should actually always be a string, the reason being is because numbers. You can only have so many variations of them, like really zero through nine. Whereas with alphanumeric strings, you can have a ton, I do think it's funny that I put that as a in quotes is a string, all right.

[00:07:46] So like I was doing an object literal for a second okay. We'll go with description is a string percent complete is a number and our favorite is going to be a Boolean, all right, there we go. I'm going to save this, now if we go back into our courses.

[00:08:18] What I'm going to do, is I'm going to outside of the class itself. I'm going to go empty course, and I'm going to type this as a course you can see now that I've imported the interface and id is gonna be no I'll address this in just a second, this is why.

[00:08:55] So now what we should see is that it's declared as never read, as well as we're missing a bunch of properties. So title is just gonna be an empty string description. Also an empty string, percent complete is gonna be zero and favorite is going to be false, all right.

[00:09:17] So, now, what I can do is I can set selected course to empty course. And so now when I come back into this what you'll see here is that everything is hopefully kosher, let me check. Alright, so mostly kosher this is the other piece. So if entry model is used within a form tag either the name attribute must be set or the form control must be defined as stand alone, that's not what we wanna do.

[00:10:02] Well, what we want to do is we need a way to attach ng model to the top level form control. And so this is what this is complaining about. And so if we go back in here this is also going to save you a bunch of pain, that if you're attaching mg model to an input that you also need to add a name attribute.

[00:10:31] Add to it like so, and I think this should work. And, lo and behold, what do you know? That absolutely nothing is happening which is good, so now when I select this you can see here that we populated the title. And this became or the value of the foreign control object became instantly populated, now if I cancel it I would imagine that here we go.

[00:11:14] So when I tried to set it to no that was not good, so this is where things get just a few extra steps to do this. So, what I'm going to do here is I'm going to create one more method. And I'm going to I'll just do this down here, I'm gonna call this just reset Select the course Or rather I can do Let's try this I'm going to essentially just create a copy of the empty course, there we go.

[00:12:16] And so all I'm doing is I'm taking this object, I'm just creating a new copy of it. And I'm setting that is the select course, JavaScript, as you know, is, unless it's a primitive value, it's passed by reference. Which can create some interesting things, especially when you're binding to the same property.

[00:12:35] If you ever wanna talk about the evils of shared mutable state, this is a really easy way to demonstrate that. So what I'm doing instead is making this immutable by or rather it is still mutable. But essentially breaking that something shared and mutable, what you need to do is either make it non mutable or not shared.

[00:12:54] So in this case, I'm calling this lead course but I'm passing in a copy of empty course. And before I forget, what I need to do now is when I call this, I just need to call reset. So we'll go here, back to this, select this and if I click cancel, you can see now I was able to reset it, and hopefully everything is AOK.

[00:13:28] And so let me add in one more property here and then let me do one more property. And then we will go on to kind of the next portion of this and I'm going to issue a challenge and we will go from there. So, in this case description and the differences this one is not required.

[00:13:54] So, if we go here and notice that when I started to type this in, it filled this in, and but it immediately went to being valid because this is required. And now that itself you can see that if I select this what we should see somewhere in here is yes.

[00:14:24] So you can see here, right down here, you have this ng invalid as well as it's saying that it's dirty, and it's been touched. In summary, nice, what are we talking about? All right, so just refresh this and we'll select, there we go, valid. And, as I type this in and you can see here that it's also filling it out here so, there we go.

[00:15:00] Now, we're gonna talk about this when we get into component driven architecture, but remember what I said about shared mutable state. So shared state is okay, mutable state is okay, but shared mutable state is the devil's playground, and let me show you why. So you'll see here, I've selected Angular 13 fundamentals.

[00:15:39] And what do you think happens when I go in and I update this title. Did you notice that, I am mutating this title and it's updating in three other places on the page? So this is not good, the reason being, is what if I started typing this in I'm like, you know what?

[00:16:14] I don't really wanna do this, well I have no way to undo this because I've already mutated the data structure. And so the question is how do I solve this, what do I do?