1
00:00:00,000 --> 00:00:03,000
So, now that we've got this form here

2
00:00:03,000 --> 00:00:04,000
and we're able to pick images,

3
00:00:04,000 --> 00:00:06,000
it's time to make sure that this form

4
00:00:06,000 --> 00:00:09,000
can also be submitted, and that we then create

5
00:00:09,000 --> 00:00:13,000
and store a new meal when that happens.

6
00:00:13,000 --> 00:00:16,000
Now when it comes to handling form submissions,

7
00:00:16,000 --> 00:00:21,000
we could do that as we do it in most React projects.

8
00:00:21,000 --> 00:00:24,000
We can go to the component that contains the form

9
00:00:24,000 --> 00:00:27,000
and then we could add the onSubmit prop

10
00:00:27,000 --> 00:00:28,000
and define a function

11
00:00:28,000 --> 00:00:31,000
that should be executed when the form is submitted.

12
00:00:32,000 --> 00:00:35,000
There, we could then prevent the browser default,

13
00:00:35,000 --> 00:00:37,000
manually collect all the data,

14
00:00:37,000 --> 00:00:40,000
and send that data to a backend.

15
00:00:40,000 --> 00:00:44,000
But again, here we already are on the backend,

16
00:00:44,000 --> 00:00:46,000
at least kind of.

17
00:00:46,000 --> 00:00:48,000
We have a full stack application

18
00:00:48,000 --> 00:00:51,000
that has both backend and frontend.

19
00:00:51,000 --> 00:00:54,000
And that's why Next.js gives us

20
00:00:54,000 --> 00:00:57,000
a more powerful and convenient pattern

21
00:00:57,000 --> 00:01:00,000
than manually handling the form submission

22
00:01:00,000 --> 00:01:03,000
and collecting the data and sending it to a server.

23
00:01:04,000 --> 00:01:08,000
Instead, we can create a function in the component

24
00:01:08,000 --> 00:01:10,000
that holds the form, for example,

25
00:01:11,000 --> 00:01:14,000
which we could call shareMeal here,

26
00:01:14,000 --> 00:01:15,000
though the name is up to you.

27
00:01:17,000 --> 00:01:21,000
And we can then add a special directive in this function,

28
00:01:21,000 --> 00:01:25,000
so inside of this function body.

29
00:01:25,000 --> 00:01:27,000
And that's the 'use server' directive.

30
00:01:29,000 --> 00:01:32,000
Now, we have seen the 'use client' directive before,

31
00:01:32,000 --> 00:01:36,000
which however was not added inside of functions,

32
00:01:36,000 --> 00:01:38,000
but inside of files.

33
00:01:38,000 --> 00:01:42,000
And then when added there, 'use client' made sure

34
00:01:42,000 --> 00:01:45,000
that the components created in that file

35
00:01:45,000 --> 00:01:47,000
would be client components.

36
00:01:49,000 --> 00:01:53,000
'use server' inside of a function is different

37
00:01:53,000 --> 00:01:57,000
because this creates a so-called Server Action,

38
00:01:57,000 --> 00:02:00,000
which is a function that's guaranteed

39
00:02:00,000 --> 00:02:04,000
to execute on the server, and only there.

40
00:02:04,000 --> 00:02:09,000
So just as components by default are server components

41
00:02:09,000 --> 00:02:11,000
which only execute on the server,

42
00:02:11,000 --> 00:02:13,000
this is now a function

43
00:02:13,000 --> 00:02:16,000
that only executes on a server.

44
00:02:16,000 --> 00:02:17,000
But in case of functions,

45
00:02:17,000 --> 00:02:21,000
you must explicitly state that it belongs to the server

46
00:02:21,000 --> 00:02:23,000
by adding this directive inside of them

47
00:02:23,000 --> 00:02:26,000
if you wanna create such a Server Action.

48
00:02:27,000 --> 00:02:30,000
In addition, to really turn this

49
00:02:30,000 --> 00:02:32,000
into a so-called Server Action,

50
00:02:32,000 --> 00:02:36,000
you also must add the "async" keyword in front of it.

51
00:02:36,000 --> 00:02:38,000
And now this is a Server Action.

52
00:02:38,000 --> 00:02:42,000
But what's now the special thing about this Server Action?

53
00:02:42,000 --> 00:02:44,000
Why does this feature exist?

54
00:02:45,000 --> 00:02:49,000
Well, this feature exists in React, by the way,

55
00:02:49,000 --> 00:02:52,000
not just in Next.js, but like server components,

56
00:02:52,000 --> 00:02:55,000
it doesn't really work in Vanilla React apps.

57
00:02:55,000 --> 00:02:58,000
Instead, you need a framework like Next

58
00:02:58,000 --> 00:03:01,000
to unlock this feature and use it.

59
00:03:01,000 --> 00:03:03,000
And this feature then exists

60
00:03:03,000 --> 00:03:06,000
because you can now take such a Server Action

61
00:03:06,000 --> 00:03:09,000
and assign this Server Action function

62
00:03:09,000 --> 00:03:13,000
as a value for the action prop on a function.

63
00:03:14,000 --> 00:03:16,000
So here, I'm setting shareMeal

64
00:03:16,000 --> 00:03:21,000
as a value on that action prop of that form here.

65
00:03:22,000 --> 00:03:24,000
And that's of course something

66
00:03:24,000 --> 00:03:26,000
you might have never seen before,

67
00:03:26,000 --> 00:03:29,000
because normally, the action prop

68
00:03:29,000 --> 00:03:34,000
is set to the path to which the request should be sent

69
00:03:34,000 --> 00:03:35,000
if you are relying

70
00:03:35,000 --> 00:03:39,000
on the browser's built-in form handling capabilities.

71
00:03:40,000 --> 00:03:41,000
Now that's not what we're doing here.

72
00:03:41,000 --> 00:03:44,000
Instead, we're setting it to an action,

73
00:03:44,000 --> 00:03:46,000
to such a Server Action function.

74
00:03:47,000 --> 00:03:49,000
And that's a pattern that's supported

75
00:03:49,000 --> 00:03:53,000
by Next and React here that will ensure

76
00:03:53,000 --> 00:03:55,000
that when this form is submitted,

77
00:03:55,000 --> 00:03:58,000
Next.js will, behind the scenes,

78
00:03:58,000 --> 00:04:02,000
create a request and send it to this Next.js server

79
00:04:02,000 --> 00:04:04,000
that's serving the website

80
00:04:04,000 --> 00:04:06,000
so that this function gets triggered,

81
00:04:06,000 --> 00:04:09,000
and you can then handle the form submission there,

82
00:04:09,000 --> 00:04:10,000
but on the server.

83
00:04:10,000 --> 00:04:13,000
So, that function will then execute on the server,

84
00:04:13,000 --> 00:04:15,000
not in the client.

85
00:04:16,000 --> 00:04:19,000
And this function will then automatically receive

86
00:04:19,000 --> 00:04:23,000
that formData that was submitted.

87
00:04:23,000 --> 00:04:27,000
So, the data that was gathered by the inputs in the form

88
00:04:27,000 --> 00:04:30,000
collected in a formData object,

89
00:04:30,000 --> 00:04:35,000
using that formData class that's available in JavaScript.

90
00:04:35,000 --> 00:04:38,000
So we'll get such a formData object here

91
00:04:38,000 --> 00:04:42,000
and we can then use that to handle the submitted data.

92
00:04:43,000 --> 00:04:46,000
For example, here, we could create a meal

93
00:04:46,000 --> 00:04:50,000
by extracting meal data from that form data.

94
00:04:50,000 --> 00:04:55,000
So we could add a title property to this meal

95
00:04:55,000 --> 00:05:00,000
and as a value store formData.get 'title'.

96
00:05:01,000 --> 00:05:03,000
This formData object that we're getting

97
00:05:03,000 --> 00:05:05,000
will have a get method that allows us

98
00:05:05,000 --> 00:05:07,000
to get the value that was entered

99
00:05:07,000 --> 00:05:09,000
into a certain input field,

100
00:05:09,000 --> 00:05:12,000
and the input field is identified by its name.

101
00:05:12,000 --> 00:05:15,000
So, if I get the value of the input field

102
00:05:15,000 --> 00:05:18,000
with the name 'title', I am getting the value

103
00:05:18,000 --> 00:05:20,000
of this input field here

104
00:05:20,000 --> 00:05:23,000
because this input field has that name, 'title'.

105
00:05:27,000 --> 00:05:29,000
And of course we can now do that

106
00:05:29,000 --> 00:05:31,000
for all the data that makes up a meal.

107
00:05:31,000 --> 00:05:34,000
So, all the data we're expecting in our database,

108
00:05:34,000 --> 00:05:37,000
like the image, the summary, the instructions,

109
00:05:37,000 --> 00:05:39,000
creator, creator_email, and so on.

110
00:05:41,000 --> 00:05:45,000
So for that here, we can also store the summary

111
00:05:45,000 --> 00:05:49,000
by getting hold of formData.get 'summary',

112
00:05:49,000 --> 00:05:51,000
extracting the data from the input field

113
00:05:51,000 --> 00:05:52,000
with the name "summary",

114
00:05:54,000 --> 00:05:59,000
get the instructions from formData.get 'instructions',

115
00:06:00,000 --> 00:06:05,000
and get the image from formData.get 'image'.

116
00:06:05,000 --> 00:06:08,000
Now, for this to work, we have to make sure

117
00:06:08,000 --> 00:06:11,000
that we pass the appropriate name

118
00:06:11,000 --> 00:06:12,000
to our ImagePicker component.

119
00:06:13,000 --> 00:06:16,000
And at the moment, I'm not doing that.

120
00:06:16,000 --> 00:06:18,000
Indeed I'm using the ImagePicker

121
00:06:18,000 --> 00:06:21,000
without setting either a label or a name,

122
00:06:21,000 --> 00:06:23,000
and I now wanna change this.

123
00:06:23,000 --> 00:06:28,000
So here I'll set the label to "Your image"

124
00:06:28,000 --> 00:06:31,000
and the name to "image", let's say.

125
00:06:33,000 --> 00:06:36,000
And with that, we make sure that we can extract that image

126
00:06:36,000 --> 00:06:38,000
with help of formData.get.

127
00:06:38,000 --> 00:06:41,000
Now, that will then be the uploaded file

128
00:06:41,000 --> 00:06:43,000
and we'll handle the storage of that file

129
00:06:43,000 --> 00:06:44,000
a little bit later.

130
00:06:46,000 --> 00:06:50,000
Now, besides that, I'll also get the creator of that meal

131
00:06:50,000 --> 00:06:53,000
by accessing formData.get 'name',

132
00:06:53,000 --> 00:06:56,000
because I'm getting that name of the person

133
00:06:56,000 --> 00:06:59,000
who created that meal from that name input field,

134
00:07:00,000 --> 00:07:03,000
so with a name of "name",

135
00:07:03,000 --> 00:07:05,000
so that's why I'm extracting it like this.

136
00:07:06,000 --> 00:07:08,000
And we got the creator_email

137
00:07:08,000 --> 00:07:11,000
with help of formData.get 'email',

138
00:07:14,000 --> 00:07:17,000
like this, and therefore that will give us that email.

139
00:07:21,000 --> 00:07:23,000
So with that, we create such a form object.

140
00:07:23,000 --> 00:07:28,000
And the next step then would be to store that in a database,

141
00:07:28,000 --> 00:07:30,000
though the image should actually be stored

142
00:07:30,000 --> 00:07:34,000
on the file system and then a path to that image

143
00:07:34,000 --> 00:07:36,000
should be stored in a database.

144
00:07:36,000 --> 00:07:38,000
But either way, the storage of this data

145
00:07:38,000 --> 00:07:40,000
is now the next step.

146
00:07:40,000 --> 00:07:42,000
But what's important to understand here

147
00:07:42,000 --> 00:07:45,000
is that you can use this Server Actions feature

148
00:07:45,000 --> 00:07:47,000
to create such a function

149
00:07:47,000 --> 00:07:50,000
that will be triggered when a form is submitted.

150
00:07:51,000 --> 00:07:53,000
And in order to see this in action,

151
00:07:53,000 --> 00:07:54,000
we'll not store that data yet,

152
00:07:54,000 --> 00:07:58,000
but instead simply log it to the console, like this.

153
00:07:59,000 --> 00:08:02,000
And with that, we can give this a try.

154
00:08:02,000 --> 00:08:06,000
If we now reload this, "Share your email page",

155
00:08:06,000 --> 00:08:10,000
and I then enter some data here, like this,

156
00:08:11,000 --> 00:08:14,000
and I then also pick an image,

157
00:08:15,000 --> 00:08:17,000
If I click Share Meal,

158
00:08:17,000 --> 00:08:20,000
and I open the developer tools before doing that,

159
00:08:20,000 --> 00:08:22,000
you see no log here,

160
00:08:22,000 --> 00:08:25,000
but you also see that the page didn't reload.

161
00:08:25,000 --> 00:08:28,000
So it looks like that default browser behavior,

162
00:08:28,000 --> 00:08:31,000
which normally would be to send the request automatically

163
00:08:31,000 --> 00:08:35,000
and therefore reload the page was prevented.

164
00:08:35,000 --> 00:08:38,000
And instead, you'll see some output here

165
00:08:38,000 --> 00:08:40,000
on the server side in your terminal,

166
00:08:40,000 --> 00:08:44,000
in that terminal where you started the development server.

167
00:08:44,000 --> 00:08:46,000
There you see that meal data.

168
00:08:47,000 --> 00:08:51,000
You see all the data I entered and that file.

169
00:08:51,000 --> 00:08:53,000
And again, we'll store that file soon.

170
00:08:55,000 --> 00:08:58,000
But with that, that's how you can handle form submissions

171
00:08:58,000 --> 00:09:00,000
with help of Server Actions.

