So, we're already providing
better user feedback,
but that's not all we should do here.
One other thing you should typically do
when handling user data and form submissions
is validate the values you are getting.
And at the moment, we're not performing any validation
at all in our server action here.
Now, we do have some validation,
because in that form,
I'm using those built-in special attributes.
Those required props here, to be precise,
to make sure that we can't submit an empty form.
So if I press submit here,
I'm getting some errors automatically by the browser.
And that's a useful behavior, but it's not enough,
because I can disable that by going through the DevTools
and removing that.
Now of course, many users won't know about that,
but some do, and in that case,
those users could submit invalid values to my backend,
because now I would not get an error
for this field anymore.
And that's why client-side validation isn't enough.
Instead, you should also validate on the server side.
And here you can now, of course,
set up some very complex validation rules.
You can use a third-party package that helps you with that.
I'll keep it fairly simple to not waste your time,
but it's important to know that you should do that
in your applications.
So, here we could, for example,
check if meal.title, once we trim it
to remove excess whitespace on the left and right,
we could check if that's then equal to an empty string,
which would mean that it's an invalid value.
We could also check if meal.title maybe even doesn't exist.
So if it's false,
so if it wasn't part of the submitted data at all.
And therefore here, we would now make it into this if block,
if we either don't have a title,
or if we have one, but it's empty.
And you should now probably do that
for all those fields.
And then over here I'll actually add a helper function,
isInvalidText, could be a fitting name,
where I expect to get some text
and where I return the result of this check
so that I return true
if the text we got is either false,
or it's an empty string after trimming it.
And now I can use isInvalidText down here
and check if meal.title is an invalid text
or if meal.summary is an invalid text,
and so on.
We can now relatively easily do that for all those fields.
So, also do it for the instructions, for the creator,
and also for the creator email.
And of course that should be meal.instructions,
meal.creator, and meal.creator_email.
And we also might wanna check whether that maybe exists,
but is an invalid email address,
so, I'll also check if meal.creator_email
does not include an @ symbol
by adding an exclamation mark here at the beginning.
So, if the email does not include an @ symbol,
we also make it into this if block.
And last but not least,
I want to check the image that we got.
I wanna check if maybe we don't have an image.
So, if it's undefined, or if that image here
has a size that's equal to zero,
which means it's some kind of invalid file.
And in all those cases I wanna make it into this if block,
and then do what?
Well, then we could throw an error.
So, we could throw an error where we say invalid input.
And by doing that, if you save that,
you ensure that if you reload here
and you then enter values into all those fields
except the email address,
and we then get rid of the required attribute
on that email field
so that we can submit it,
if we do all that, UCI gets this error page.
Now, the error message here is a bit misleading,
because it's that main error page which we set up earlier.
We should probably set up a specific error page
for sharing a meal.
So, I will copy that here, paste it here,
and say, "Failed to create meal."
That sounds better.
But the important thing is that we got some error at all.
However, that's just one way of handling this.
Throwing an error as we do it here works,
but it also means that we destroy
the entire input of the user.
So, we throw away everything they entered.
And that's not necessarily a great user experience.
It would be better if we would stay on this page
and just output some error message somewhere on this page,
above the form or below the form, for example.
And that's therefore what we'll implement next.