Transcript
00:00 When we submit this form, we're going to be making a GET request right here, and that GET request is going to include everything in the URL. This is great for some situations, like say you're searching for a product on some e-commerce site, you have all your filters set up and everything, and the product that you're looking
00:18 for isn't there yet, but you think it might, so you're going to bookmark that. Next time you come back to look at that bookmark, you're going to hopefully see it. Or maybe you share it with somebody else. You want all of your filters to be saved in that URL. However, for an onboarding form like this, it doesn't make sense because we've got our password in there, we're trying to submit a photo, all that stuff.
00:37 So we can't use a GET request, because the only place that the form data can go in a GET request is the URL. So we have to use something else, and the something else we're going to use is POST. Now this is one of only three valid options for method.
00:53 You have GET as the default, you have POST, and then you also have DIALOG. We're not going to get into DIALOG. This is really, that's for opening DIALOG, so it's kind of interesting, or closing. But yeah, so we're not going to be doing that.
01:08 But we, now with the method POST, we can submit the form and not have all the values serialized in the URL. Now before we, well here, let's go ahead and submit it. You'll see we get this error, because we're making a non-GET request to the API endpoint. So let's go over to our API, and we're going to change from Loader to Action.
01:27 So this again is just the workshop app setting this up for us. It has an API that is similar to Remix. And so Loader handles GET requests, Action handles non-GET requests. So this will handle our POST.
01:43 Now because our onboarding request no longer has the data in the URL, but instead has it serialized as like a URL in form data as part of the body of the request, we need to convert that form data into our data that we can access. It's no longer coming from the search params.
02:01 So we're going to await request form data, and this is going to grab the body and turn it into a form data object, which we can then use. And so with that all set up here, we can submit. And now we are getting the data that we want. Our request is successful.
02:20 All that stuff is good. So our backend is now ready. And that's the impact that you make on the backend when you change from a method GET to a method POST, is now the backend needs to consume the form submission rather than from the URL, instead from the request body. And in our case, we just grab it from the form data utility or API.
02:40 It's a web standard API. Okay, great. So method POST, that's a good thing. We're no longer going to have the password in the URL. If I go and say some password, there we go. We're going to see our password right there because the backend sent it back to us.
02:58 But your backend probably wouldn't do that. And it's going to be serialized in the body of the request, but it's not going to appear in the URL. So it's not going to show up in people's logs. It's not going to show up in their history. It's not going to show up on the screen for people to see because it's in the request body.
03:18 Okay, great. So the next problem that we need to deal with here is when I choose this amazing photo and submit that, we're seeing the photo is just this string, which is the name of the file. That's what we submitted.
03:34 And if we take a look at the request submission, view the source of that, it's literally just saying, hey, the photo is assigned to this string. So that's the default behavior also. Not great for file uploads. So we need to change the encoding type.
03:51 So the URL search param or that URL serialized string is not sufficient for handling files. We need to have a different encoding type. And so we're going to say type is equal to multi-part form data.
04:07 This is as opposed to the default behavior, which you'll find right here in our request headers. If we go down to, yeah, here it is, content type, application X, the X hyphen prefix is saying this is not standard.
04:23 Well, it turns out that all the browsers implemented this and it became the standard anyway, which always gives me a chuckle whenever I see that X dash. But yeah, it's WWW form URL encoded. So that's the default behavior for form. We are changing the encoding type to be multi-part form data.
04:42 This means that it can send parts of the data that is in the submission. It can send it in multiple parts in chunks. And so the cool thing about that is you can upload like a hundred megabyte or a hundred gigabyte video. And of course, not many people have that much memory.
05:01 And so you don't have to load it up all in memory at once. You can just take little chunks of it, send that chunk, then take another part, send that part, take another part, send that. So that is what the multi-part is all about. If we come back here now and we choose a file and let's clear this out to make it clear when you hit that submit.
05:21 And now, oh, I forgot to save it. Oh man. Okay. That's a good lesson for you at home kids. Make sure you save your files. Okay. So we come back here, hit submit, and we're going to get our photo.
05:34 And the way that that works now is we take a look at our request handler right here, multi-part form data. And what's interesting here, let's expand this a bit so we can see it a little better. So this multi-part form data has this boundary thing. So that's a semicolon right there. That's their delimiter.
05:53 And then this is like some additional configuration for the content type. So the boundary equals this dash dash dash webkit form boundary xm dot dot dot whatever. This is used in the payload. So the payload ends up just being a string. Everything is serialized to a string when it's sent over the wire.
06:12 And so we have to have some delimiter, some way to say, okay, here's this part of the form. Here's this part of the form. Here's this part of the form. And so that is what that delimiter is all about. So if we look at the source, we're going to have that familiar string right there. And then here's our content disposition. This is form data. And here's the property name.
06:32 And here's the value. And then we've got another form data for the password, which of course doesn't have a value. And right here, we're going to see where we have a value. So the file name for this form data is going to be this value. And then our content type is image JPEG.
06:51 And then we can continue. One thing that this is not showing us is the binary data. But we can see that right here under photo that's binary. So yeah, it's not going to show us all the serialized version of the photo, but that will be represented in the request here.
07:10 And from that then on the back end, they can grab that from the request body, use some library to parse it out or parse it themselves if they want to. And then in our case, we're sending it back so that we can display it here. And if you take a look at what we're doing, we just say data URL.
07:29 We have a base 64 encoded version of the image. That's how we're doing it. But the important thing for you and your React and web knowledge in general is that we set the encoding type to multi-platform data. And now you can do file upload.
07:44 That is pretty much the default for any time you're going to be doing a file upload. Not necessarily every form will need this. But yeah, if you want to do a file upload, you're pretty much going to have to do this. Okay, great. So then we're going to add an on submit handler because I don't want to call the back end anymore.
08:03 I want to do everything here on the front end. And this is going to call event prevent default. The reason that I want to do everything on the front end is because I don't want full page refreshes. Full page refreshes are pretty inefficient because you have to reparse and reevaluate all the JavaScript you got on the client.
08:22 You have to worry about managing focus and error management and all of that stuff. Like animations, we've got view transitions now, which is kind of nice. But a lot of things are easier if you just do it on the client. You don't always have to in their reasonable situations where a full page refresh and let the browser just do its thing can be useful.
08:42 But we're going to override that behavior and enhance the experience a little bit. So with that, now, if I submit this, nothing is going to happen. Nothing at all. You'll see no requests are going on. Nothing is going on. This is not great.
08:56 Of course, we just like broke the entire experience, but we're going to do things in the browser instead. So inside of this on submit handler, we're going to create a form data object, just like we were doing on the back end where we parsed things as form data. You can actually do this on the front end as well.
09:15 So let's get our form data that's going to come from. Come on, AI assistant. You know what I'm doing. There we go. From the form data constructor, you pass a form. So that's what event dot current target is. This is referencing the form. And with that form data, we'll say, oh, great, let me take all the values or the inputs that
09:33 are inside that form, turn that into a form data object. And now here you go with your form data object. So then we can log all of the form data, make an object out of the form data, just like a regular object. And we'll log that. I want to give you an idea of what all this stuff is, though.
09:50 So let's console log event dot current target or we'll put this in an object. So here's our form form data and then our entries right there.
10:00 So save this and we'll do a couple of values in here and including a photo and a cool color and we'll set this to November. There we go. And then submit this.
10:18 And here we can see our form is actually a reference to the form element itself. So that event current target, that is a reference to the element, the form element dom node. The form data is a special object that has a couple of properties on it, like get and
10:35 set and a bunch of other things like that, like getting entries and stuff, not something that is necessarily easy to work with all the time, but very it's Web standard and very useful when you're working with forms. And then finally, we have our entries and that is we just converted our form data into
10:55 an object. Now, you don't always want to do this because form data can actually represent multiple values with the same name. You can't do that with an object. And they're like legit reasons to do that, which we won't get into in this workshop.
11:07 But it is the form data API is a good one that is worth learning and using throughout your application in the future as a web dev. But to simplify things, we convert it to this object and now we've got an object of all of these values.
11:25 And in fact, one interesting thing here is the photo is a file. So this is another Web standard object that has information about the file. You can read the image and everything from that file. We're not going to go that deep into it, but that is something else to take a look at. That's kind of interesting. All right, there you go.
11:45 Now here we'll do this extra credit. We can see what happens if we remove all of this stuff, refresh and we hit submit. And because we're preventing the default behavior here, actually, let's select a photo and then submit that because we're doing the default behavior or preventing the default behavior.
12:04 We don't have to worry about the form and coding. We're not submitting it anymore, so we don't need to worry about the action or the method or any of that stuff because the browser is not doing anything. We are typically I'm not using on submit myself. But yeah, once you add on submit and a prevent default, then you don't have to worry about
12:23 those other attributes because, yeah, they're not like you don't have to use them. So just another fun little thing for you to understand. There's a whole big topic around this, around something called progressive enhancement, which we cannot use because this is a fully client side app anyway.
12:42 And so it's not like somebody could submit this form if we aren't ready to handle the submission. But yeah, there's there's a big thing once you start talking about server rendering and stuff, a reason why still including those could be useful. But yeah, for our simple little app, this works out quite nicely.
13:01 I know that was a lot, but hopefully that gives you a better understanding of the how to encode a request for our form submission so that you can handle form uploads and how to properly encode things so that they don't show up in the URL.
13:19 So yeah, that was a good time with setting our method encoding type and adding an on submit handler so we can interact with this stuff in the client.