So, now that we've got this form here
and we're able to pick images,
it's time to make sure that this form
can also be submitted, and that we then create
and store a new meal when that happens.
Now when it comes to handling form submissions,
we could do that as we do it in most React projects.
We can go to the component that contains the form
and then we could add the onSubmit prop
and define a function
that should be executed when the form is submitted.
There, we could then prevent the browser default,
manually collect all the data,
and send that data to a backend.
But again, here we already are on the backend,
at least kind of.
We have a full stack application
that has both backend and frontend.
And that's why Next.js gives us
a more powerful and convenient pattern
than manually handling the form submission
and collecting the data and sending it to a server.
Instead, we can create a function in the component
that holds the form, for example,
which we could call shareMeal here,
though the name is up to you.
And we can then add a special directive in this function,
so inside of this function body.
And that's the 'use server' directive.
Now, we have seen the 'use client' directive before,
which however was not added inside of functions,
but inside of files.
And then when added there, 'use client' made sure
that the components created in that file
would be client components.
'use server' inside of a function is different
because this creates a so-called Server Action,
which is a function that's guaranteed
to execute on the server, and only there.
So just as components by default are server components
which only execute on the server,
this is now a function
that only executes on a server.
But in case of functions,
you must explicitly state that it belongs to the server
by adding this directive inside of them
if you wanna create such a Server Action.
In addition, to really turn this
into a so-called Server Action,
you also must add the "async" keyword in front of it.
And now this is a Server Action.
But what's now the special thing about this Server Action?
Why does this feature exist?
Well, this feature exists in React, by the way,
not just in Next.js, but like server components,
it doesn't really work in Vanilla React apps.
Instead, you need a framework like Next
to unlock this feature and use it.
And this feature then exists
because you can now take such a Server Action
and assign this Server Action function
as a value for the action prop on a function.
So here, I'm setting shareMeal
as a value on that action prop of that form here.
And that's of course something
you might have never seen before,
because normally, the action prop
is set to the path to which the request should be sent
if you are relying
on the browser's built-in form handling capabilities.
Now that's not what we're doing here.
Instead, we're setting it to an action,
to such a Server Action function.
And that's a pattern that's supported
by Next and React here that will ensure
that when this form is submitted,
Next.js will, behind the scenes,
create a request and send it to this Next.js server
that's serving the website
so that this function gets triggered,
and you can then handle the form submission there,
but on the server.
So, that function will then execute on the server,
not in the client.
And this function will then automatically receive
that formData that was submitted.
So, the data that was gathered by the inputs in the form
collected in a formData object,
using that formData class that's available in JavaScript.
So we'll get such a formData object here
and we can then use that to handle the submitted data.
For example, here, we could create a meal
by extracting meal data from that form data.
So we could add a title property to this meal
and as a value store formData.get 'title'.
This formData object that we're getting
will have a get method that allows us
to get the value that was entered
into a certain input field,
and the input field is identified by its name.
So, if I get the value of the input field
with the name 'title', I am getting the value
of this input field here
because this input field has that name, 'title'.
And of course we can now do that
for all the data that makes up a meal.
So, all the data we're expecting in our database,
like the image, the summary, the instructions,
creator, creator_email, and so on.
So for that here, we can also store the summary
by getting hold of formData.get 'summary',
extracting the data from the input field
with the name "summary",
get the instructions from formData.get 'instructions',
and get the image from formData.get 'image'.
Now, for this to work, we have to make sure
that we pass the appropriate name
to our ImagePicker component.
And at the moment, I'm not doing that.
Indeed I'm using the ImagePicker
without setting either a label or a name,
and I now wanna change this.
So here I'll set the label to "Your image"
and the name to "image", let's say.
And with that, we make sure that we can extract that image
with help of formData.get.
Now, that will then be the uploaded file
and we'll handle the storage of that file
a little bit later.
Now, besides that, I'll also get the creator of that meal
by accessing formData.get 'name',
because I'm getting that name of the person
who created that meal from that name input field,
so with a name of "name",
so that's why I'm extracting it like this.
And we got the creator_email
with help of formData.get 'email',
like this, and therefore that will give us that email.
So with that, we create such a form object.
And the next step then would be to store that in a database,
though the image should actually be stored
on the file system and then a path to that image
should be stored in a database.
But either way, the storage of this data
is now the next step.
But what's important to understand here
is that you can use this Server Actions feature
to create such a function
that will be triggered when a form is submitted.
And in order to see this in action,
we'll not store that data yet,
but instead simply log it to the console, like this.
And with that, we can give this a try.
If we now reload this, "Share your email page",
and I then enter some data here, like this,
and I then also pick an image,
If I click Share Meal,
and I open the developer tools before doing that,
you see no log here,
but you also see that the page didn't reload.
So it looks like that default browser behavior,
which normally would be to send the request automatically
and therefore reload the page was prevented.
And instead, you'll see some output here
on the server side in your terminal,
in that terminal where you started the development server.
There you see that meal data.
You see all the data I entered and that file.
And again, we'll store that file soon.
But with that, that's how you can handle form submissions
with help of Server Actions.