Check out a free preview of the full Fullstack Svelte with SvelteKit course
The "Form Validation" Lesson is part of the full, Fullstack Svelte with SvelteKit course featured in this preview video. Here's what you'd learn in this lesson:
Rich discusses validating user-submitted data using the browser's built-in form validation and further protection from incorrect user input using server-side validation. SvelteKit will direct users to an error page by default which can be avoided by utilizing the fail helper function that returns data from the action along with the HTTP status code.
Transcript from the "Form Validation" Lesson
[00:00:00]
>> Now one thing that you've learned very quickly as a web developer is that you cannot trust users, they will cause chaos given the chance. And we need to make sure that they're not gonna submit gibberish data using our forms. The first line of defense is the browser's built in validation, which makes it easy to for example, mark the input as required.
[00:00:19]
So let's go to the add to-do input. I'm just gonna add the required attribute. And now if you're try and submit a to-do without any data, we'll see a notification from the browser saying, please fill out this field. This kind of validation, is helpful, and you absolutely should add it, gives you a nice user interface for free, but it's also insufficient.
[00:00:43]
There are some validation rules that can't be encoded using these attributes, for example, you might have a uniqueness requirement. In any case, if the user knows how to use DevTools, then they might just go in and get rid of the required attribute or something like that. So to guard against people doing malicious things like that, you should always use server side validation, as well as client side validation.
[00:01:03]
If you have a choice, do the server side validation first. So all right, and in the database JS file we're gonna do the validation when someone calls createTodo. First thing we'll do is if description is empty. We'll throw an error. And the error is gonna be todo must have a description.
[00:01:40]
And then we're gonna get the user's existing todos so that we can do a uniqueness check. If todos.find(todo), Todo.description, Is equal the description that we've just submitted, well, then we're gonna throw an error that says todos must be unique. Right, and so now if we submit a duplicate todo, We get an error page.
[00:02:19]
It's probably not exactly what we want, but it's a good start. It would be nice if we could stay on the same page where the form was submitted and give the user an opportunity to correct them, their mistake. So inside our page.server.js file, we're gonna import a new module, fail from SvelteKit.
[00:02:41]
And inside our create action, once we got the data, we're gonna try to create the Todo. And if it fails, we catch the error. And we're gonna return a fail object. Given an HTTP code of 422, which indicates that there was something wrong with the data that was submitted.
[00:03:12]
We'll pass the description back to the page so that we can render it in the UI. We don't just pass all of the data that the user submitted back automatically, because they could include things like passwords and credit card data that we wanna be careful about where we put that.
[00:03:30]
And finally, the error property of this fail object is gonna be the message that was thrown from the Create todo function. You have a question from the internet?
>> What's the difference between the fail and error helpers from SveltKit?
>> Yep, so we're gonna get into the weeds of error handling later on.
[00:03:53]
But essentially if you just throw new error with some message, then SvelteKit is gonna throw his hands up say, I don't know what to do with this. I'm just gonna render an error page and I'm gonna tell the user that an internal error happened. If you throw an error that was created with the error helper from SvelteKit, then SvelteKit is like, okay, the user, the developer knows what they're doing, this is an error that they expected.
[00:04:21]
And so will actually display the message of that error to the user instead of a generic internal error. When you're submitting form data, this isn't an application error. If the data is wrong, it's a validation error. And we wanna be able to distinguish between errors that should result in the error page being shown and errors that should be sent back to the user, so that it can be incorporated into the UI without showing an error page.
[00:04:47]
And that's where this fail helper comes in. So an action can return data, which is made available to the page. And by wrapping it in this fail function, we're telling SvelteKit that the user submitted incorrect data. And that's useful for displaying the correct status code and things like that.
[00:05:17]
Okay, so in our page.svelte, we can now access the data that was returned from the action via the form prop, which sits alongside export let data. So let's create that export let form. And below the h1 we'll add an if block. If form?.error, the question mark is there because if we're on this page and we haven't just submitted some data form won't exist.
[00:05:43]
But if the form object does exist and it contains an error property, then we know that we need to render some error UI. P class equals error and then we're just gonna display form.error to the user. And finally, we're gonna add the value that was previously submitted in the description to the input so that the user doesn't have to retype it.
[00:06:16]
So if the form exists, we'll grab the description. If it doesn't, then we'll default to the empty string. Okay, so this time, if we do the same thing, we try and submit a duplicate todo, Learn SvelteKit. Well, that's embarrassing. I must have missed a part here. I must have missed a bar here, I'm gonna open the terminal, see what happened.
[00:06:38]
Okay, data.get is not a function. So, there's an error in my code. We'll go to page.server.js and see where that's happening. Is because you'll notice up here this data object, I called await request form data, but I forgot to add the parentheses somehow. So, I'll fix that.
[00:07:00]
And now, when I add the duplicate todo, It's gonna display the error that was thrown from the create todo function.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops