1
00:00:00,000 --> 00:00:02,000
So, we're already providing

2
00:00:02,000 --> 00:00:04,000
better user feedback,

3
00:00:04,000 --> 00:00:06,000
but that's not all we should do here.

4
00:00:07,000 --> 00:00:09,000
One other thing you should typically do

5
00:00:09,000 --> 00:00:13,000
when handling user data and form submissions

6
00:00:13,000 --> 00:00:17,000
is validate the values you are getting.

7
00:00:18,000 --> 00:00:21,000
And at the moment, we're not performing any validation

8
00:00:21,000 --> 00:00:24,000
at all in our server action here.

9
00:00:25,000 --> 00:00:28,000
Now, we do have some validation,

10
00:00:28,000 --> 00:00:30,000
because in that form,

11
00:00:30,000 --> 00:00:33,000
I'm using those built-in special attributes.

12
00:00:33,000 --> 00:00:37,000
Those required props here, to be precise,

13
00:00:37,000 --> 00:00:41,000
to make sure that we can't submit an empty form.

14
00:00:41,000 --> 00:00:42,000
So if I press submit here,

15
00:00:42,000 --> 00:00:46,000
I'm getting some errors automatically by the browser.

16
00:00:46,000 --> 00:00:50,000
And that's a useful behavior, but it's not enough,

17
00:00:50,000 --> 00:00:54,000
because I can disable that by going through the DevTools

18
00:00:54,000 --> 00:00:56,000
and removing that.

19
00:00:56,000 --> 00:00:59,000
Now of course, many users won't know about that,

20
00:00:59,000 --> 00:01:01,000
but some do, and in that case,

21
00:01:01,000 --> 00:01:06,000
those users could submit invalid values to my backend,

22
00:01:06,000 --> 00:01:08,000
because now I would not get an error

23
00:01:08,000 --> 00:01:09,000
for this field anymore.

24
00:01:11,000 --> 00:01:15,000
And that's why client-side validation isn't enough.

25
00:01:16,000 --> 00:01:19,000
Instead, you should also validate on the server side.

26
00:01:19,000 --> 00:01:21,000
And here you can now, of course,

27
00:01:21,000 --> 00:01:25,000
set up some very complex validation rules.

28
00:01:25,000 --> 00:01:30,000
You can use a third-party package that helps you with that.

29
00:01:30,000 --> 00:01:34,000
I'll keep it fairly simple to not waste your time,

30
00:01:34,000 --> 00:01:37,000
but it's important to know that you should do that

31
00:01:37,000 --> 00:01:38,000
in your applications.

32
00:01:39,000 --> 00:01:40,000
So, here we could, for example,

33
00:01:40,000 --> 00:01:44,000
check if meal.title, once we trim it

34
00:01:44,000 --> 00:01:48,000
to remove excess whitespace on the left and right,

35
00:01:48,000 --> 00:01:51,000
we could check if that's then equal to an empty string,

36
00:01:51,000 --> 00:01:54,000
which would mean that it's an invalid value.

37
00:01:55,000 --> 00:01:59,000
We could also check if meal.title maybe even doesn't exist.

38
00:02:00,000 --> 00:02:02,000
So if it's false,

39
00:02:02,000 --> 00:02:05,000
so if it wasn't part of the submitted data at all.

40
00:02:06,000 --> 00:02:09,000
And therefore here, we would now make it into this if block,

41
00:02:09,000 --> 00:02:11,000
if we either don't have a title,

42
00:02:11,000 --> 00:02:13,000
or if we have one, but it's empty.

43
00:02:15,000 --> 00:02:17,000
And you should now probably do that

44
00:02:17,000 --> 00:02:19,000
for all those fields.

45
00:02:19,000 --> 00:02:22,000
And then over here I'll actually add a helper function,

46
00:02:22,000 --> 00:02:26,000
isInvalidText, could be a fitting name,

47
00:02:26,000 --> 00:02:29,000
where I expect to get some text

48
00:02:29,000 --> 00:02:33,000
and where I return the result of this check

49
00:02:33,000 --> 00:02:35,000
so that I return true

50
00:02:35,000 --> 00:02:39,000
if the text we got is either false,

51
00:02:39,000 --> 00:02:41,000
or it's an empty string after trimming it.

52
00:02:43,000 --> 00:02:47,000
And now I can use isInvalidText down here

53
00:02:47,000 --> 00:02:51,000
and check if meal.title is an invalid text

54
00:02:52,000 --> 00:02:57,000
or if meal.summary is an invalid text,

55
00:02:58,000 --> 00:03:00,000
and so on.

56
00:03:00,000 --> 00:03:05,000
We can now relatively easily do that for all those fields.

57
00:03:05,000 --> 00:03:10,000
So, also do it for the instructions, for the creator,

58
00:03:13,000 --> 00:03:16,000
and also for the creator email.

59
00:03:16,000 --> 00:03:19,000
And of course that should be meal.instructions,

60
00:03:19,000 --> 00:03:22,000
meal.creator, and meal.creator_email.

61
00:03:25,000 --> 00:03:28,000
And we also might wanna check whether that maybe exists,

62
00:03:28,000 --> 00:03:30,000
but is an invalid email address,

63
00:03:30,000 --> 00:03:33,000
so, I'll also check if meal.creator_email

64
00:03:36,000 --> 00:03:40,000
does not include an @ symbol

65
00:03:40,000 --> 00:03:43,000
by adding an exclamation mark here at the beginning.

66
00:03:43,000 --> 00:03:47,000
So, if the email does not include an @ symbol,

67
00:03:47,000 --> 00:03:49,000
we also make it into this if block.

68
00:03:50,000 --> 00:03:51,000
And last but not least,

69
00:03:51,000 --> 00:03:54,000
I want to check the image that we got.

70
00:03:55,000 --> 00:03:58,000
I wanna check if maybe we don't have an image.

71
00:03:59,000 --> 00:04:03,000
So, if it's undefined, or if that image here

72
00:04:03,000 --> 00:04:05,000
has a size that's equal to zero,

73
00:04:05,000 --> 00:04:08,000
which means it's some kind of invalid file.

74
00:04:10,000 --> 00:04:14,000
And in all those cases I wanna make it into this if block,

75
00:04:14,000 --> 00:04:16,000
and then do what?

76
00:04:16,000 --> 00:04:20,000
Well, then we could throw an error.

77
00:04:20,000 --> 00:04:23,000
So, we could throw an error where we say invalid input.

78
00:04:25,000 --> 00:04:28,000
And by doing that, if you save that,

79
00:04:28,000 --> 00:04:32,000
you ensure that if you reload here

80
00:04:32,000 --> 00:04:35,000
and you then enter values into all those fields

81
00:04:35,000 --> 00:04:38,000
except the email address,

82
00:04:39,000 --> 00:04:44,000
and we then get rid of the required attribute

83
00:04:44,000 --> 00:04:45,000
on that email field

84
00:04:45,000 --> 00:04:47,000
so that we can submit it,

85
00:04:47,000 --> 00:04:51,000
if we do all that, UCI gets this error page.

86
00:04:52,000 --> 00:04:56,000
Now, the error message here is a bit misleading,

87
00:04:56,000 --> 00:05:00,000
because it's that main error page which we set up earlier.

88
00:05:00,000 --> 00:05:03,000
We should probably set up a specific error page

89
00:05:03,000 --> 00:05:05,000
for sharing a meal.

90
00:05:06,000 --> 00:05:09,000
So, I will copy that here, paste it here,

91
00:05:09,000 --> 00:05:14,000
and say, "Failed to create meal."

92
00:05:14,000 --> 00:05:15,000
That sounds better.

93
00:05:17,000 --> 00:05:20,000
But the important thing is that we got some error at all.

94
00:05:21,000 --> 00:05:24,000
However, that's just one way of handling this.

95
00:05:24,000 --> 00:05:26,000
Throwing an error as we do it here works,

96
00:05:26,000 --> 00:05:29,000
but it also means that we destroy

97
00:05:29,000 --> 00:05:32,000
the entire input of the user.

98
00:05:32,000 --> 00:05:35,000
So, we throw away everything they entered.

99
00:05:35,000 --> 00:05:39,000
And that's not necessarily a great user experience.

100
00:05:39,000 --> 00:05:41,000
It would be better if we would stay on this page

101
00:05:41,000 --> 00:05:46,000
and just output some error message somewhere on this page,

102
00:05:46,000 --> 00:05:50,000
above the form or below the form, for example.

103
00:05:50,000 --> 00:05:52,000
And that's therefore what we'll implement next.

