Simulating Spam Submissions0:00
Now, at the moment, our form is working, which is great, but it's still a little naive. Anyone who's ever deployed a form to production before knows that people will take advantage and do all sorts of stupid things. So to illustrate this, what if I were to create a dummy User? But before I submit this, we're going to simulate somebody who just spams that submit button. So what I'll do here is because it's so fast, even with throttling, I'm going to go to my routes file and artificially add some throttling here. So right here, I'm going to sleep for three seconds. Okay. So yeah.
Manual Processing State1:00
So the common convention for dealing with this is to automatically disable the button. Just assume that the User is guilty and they're going to do something weird. So disable the button immediately. Okay. So if we were to do that manually, which is what we often do, we might go to our User create form. And right down here, we're now going to track if, and I'll pull in ref here, we're going to track if the form is currently processing. Has it been submitted? Okay.
Has it been submitted? Okay. We'll say let processing equals ref. And by default, no, you haven't submitted the form. It's not processing. And now why don't we just say to start right when we submit the form and we call this method, let's update processing to true. So processing.value, because again, we have that ref there. So to get the underlying Boolean, we have to call that value, which is kind of annoying to be honest, but that would do it.
So to get the underlying Boolean, we have to call that value, which is kind of annoying to be honest, but that would do it. All right. Next, if I scroll up to our button, let's say disable the button if the form is currently processing. Okay. Last little thing, let's just comment this out temporarily so that we don't redirect too quickly because I mostly just want to see that button deactivate. Okay. We come back to Firefox, try to create a dummy User.
Okay. We come back to Firefox, try to create a dummy User. And when I click submit, it looks like the button doesn't have any disabled styling. But if we select it, sure enough, it is disabled. And if we come to our component itself, processing should be set to true. And it is. Okay. So this prevents the situation where we are submitting the form too many times. As many times as I click on it, we're not performing that AJAX request again. Okay.
Hooking Into Request Events2:45
As many times as I click on it, we're not performing that AJAX request again. Okay. But of course, we want to turn this on and off conditionally. So one way we could do this is to bring this back. And as part of the third argument, we can provide options for Inertia. And some of those options are event hooks. For example, when you start the request or when you finish the request. All right, let's use those. So when you start, why don't we say processing.value is true. And when you finish, let's make it false.
So when you start, why don't we say processing.value is true. And when you finish, let's make it false. Okay. So let's test it out. First, let's do something that will fail the validation. So maybe on the password, I'll disable that required attribute just so I can bypass the browser validation. Okay. Next, let's fill this out. But we won't provide a password.
Switching to useForm3:57
It works. So we try it again. But notice I can't click it anymore because it's currently disabled. Okay. So you've probably done this a million times if you've ever built a client-side form. But what's nice is, if you want, Inertia can automate some of this stuff for you. Now, the first thing we're going to do is pull in useForm from the Inertia adapter. And I'm using vue3 here. Then I can replace this call to reactive with useForm. So this is how we would do it with the composition API.
Then I can replace this call to reactive with useForm. So this is how we would do it with the composition API. If you're using Vue 2 or something, you might instead do this.inertia.form. And then you would provide your fields here. So it's just a slight tweak to how you do it with the composition API versus the options API. Okay. So that will automatically be reactive. But now we sort of have this form on steroids, which means Inertia will automatically collate and track information about the form, including whether or not it's currently processing, which means I no longer have to do that myself.
and track information about the form, including whether or not it's currently processing, which means I no longer have to do that myself. And that means I can get rid of that import. And even better, I no longer have to manually track this processing property. Instead, well, to start, I can just remove it entirely. But because we're already using form, I can instead rewrite this like so. And now I can remove that Inertia import. Kind of cool, isn't it? So the only thing we need to update now is we don't have processing at the top level. We now access it through the form helper.
So the only thing we need to update now is we don't have processing at the top level. We now access it through the form helper. So form.processing. Or if we want to grab the errors, we can get rid of that. We can just do form.errors. So let's grab all occurrences of errors, and I'm going to replace that with form.errors. Like so. Okay, let's give it a shot. So I come back to Firefox, we give it a refresh. And first, I want you to have a look at ViewDevTools.
Exploring Form Helper Features5:52
So I come back to Firefox, we give it a refresh. And first, I want you to have a look at ViewDevTools. So if we look here, yeah, notice in our form object, and notice here we have the restful endpoints you'd expect, like making a DELETE request, or a POST request, or a PATCH request. We have information about any errors. We can check if the form is currently dirty, if it's currently processing, what the progress is. If it was recently submitted, we can even reset the form. So for example, why don't we play around with that real quick? Let's just say, setTimeout, and I'm going to reset the form, just as an illustration.
So for example, why don't we play around with that real quick? Let's just say, setTimeout, and I'm going to reset the form, just as an illustration. form.reset after three seconds. As you'd expect, that's going to clear out the form. So refresh, let's quickly fill it out. And that should be about three seconds, and it resets. So you get all of this stuff for free when you pull in Inertia's form helper. Okay, so the only remaining step is just to make sure this works. So I'm going to turn off that sleep, come back, give it a refresh, and we'll set up Jane Doe's account.
