So to finish this section
and to learn a bit more about data mutations with NextJS,
I wanna make this like button here work
so that for a given post I can click it,
and well, this post will get marked as liked by me.
Now for that in the database,
I actually already got a likes table
that is set up when the database file is created
where I'll in the end store a user ID/post ID combination
so that every user can like every post exactly once.
And of course they can also unlike it.
Now when selecting all posts, I got some query in there
where in the end I find out whether a post is being liked
by a specific user by checking whether the user
with their ID likes a post with a given ID.
And here I always assume that it's the user with ID two
because I can't make that user specific at this point
because we got no way of switching users
or logging in with users.
That's why in this section we assumed
that posts are always created by a user with ID one,
and vice versa, I always assume that it's always the user
with the ID two that may be liking a post here
so that it's a different user that's now logged in
that can view the posts and that can like the posts.
That's why this is hard coded like this here
as mentioned multiple times.
Later you will learn how to actually work with users
and how to log in and so on.
But that's the logic here.
And in the end here,
I then create a new IsLiked property on the retrieved data
that is either true or false.
In the end, depending on whether a given user
has created a like entry in that likes table
for a given post.
And those like entries are created or removed
with help of this updatePostLikeStatus function here,
where I find out whether a given user with a given ID,
which will be ID two here in this application
is liking a post or not.
So whether a user has an entry in that likes table or not,
and if they don't have one, I insert one.
If they did have one I delete it
whenever this button is pressed.
That's the plan.
Now to bring that plan to life,
we of course have to bring that button to life,
and for that we should go to that posts.js file
in the components folder
where I have a post component
because it's in there where I'm outputting my post items
and where I have this like button.
And the goal now is to make sure
that whenever the like button is pressed,
we actually trigger some code
that creates a new post user ID entry in the likes table
or removes it
with help of this updatePostLikeStatus function
I just showed you.
Now how can we make this work?
Well, we can make it work with help of a new Server Action
because in the end when that button is pressed,
we also wanna submit some data to the Server
and we wanna update the database.
So again, it's in the end another form submission
we're dealing with here.
Therefore, we could create a Server Action here
or do it in that separate actions file
which we created earlier.
And that's indeed what I'll do here.
So in that actions folder, in the posts.js file there,
I'll export a new async function
called togglePostLike status.
And I expect to get the ID of the post
for which I wanna change the like status.
And I then wanna call this update post like status function.
So this function which will update the database.
Now this function wants a post ID and a user id.
And as I mentioned before,
here I'll hardcode the user ID to two,
so to that user with the ID two,
but of course the post ID should be
the post ID we're receiving as a argument here.
And that's then essentially all.
Back in the post component here,
I'd therefore now wanna trigger that Server Action
that we just added whenever this like button is pressed.
And there are two ways of doing that.
One way of doing it
would be to go to the actual button element
which is defined in the like button.
And it turns out
that there you can indeed set a form action prop,
which also accepts such a form action as a value.
So we could accept this action as a input here
and bind that to this button.
And then in the post component,
we could pass the action prop to the like button.
And the value I wanna pass here should of course be
that togglePostLikeStatus action we just worked on,
which therefore is imported from that actions folder
and the posts file there.
That would be one way of making it work
because you can not just use Server Actions
as a value for the action prop on a form,
but also instead as a value for the form action prop
on a button.
That's one way of using them.
However, that's not what I'll do here,
even though it would work fine.
Instead I'll simply wrap this like button with a form here.
Because there's nothing wrong with doing that.
And I'll then set this action prop
directly here on the form.
So that's in the end, the same approach I used
for the new post page form.
With that, whenever this button is pressed,
it will be this action, this function
that will be triggered.
Now theoretically that's all we need to do.
However, if we save everything and I reload here,
and I click this button, it stays in that unliked mode.
Now to some extent that makes sense
because we haven't added any logic here
anywhere in our markup that would change the appearance
of that button or of that icon in that button
depending on whether the post is liked or not.
So we should change that,
and we can change that by adding a class here,
a CSS class to that form or to that div, doesn't matter,
but it should be on some parent element of this like button.
And here I want to add a class conditionally
based on whether that post is liked or not.
And this isLiked property will exist on the posts
that are retrieved from the database
because in my code where I am retrieving posts
from the database, I do define this isLiked property
based on whether the user with the ID two
does like that post or not.
So this isLiked property exists,
and it will be true if the user does like that post
and false otherwise.
So if the post is liked, I wanna add a class of liked
to that form element and otherwise I won't add any class.
And in the global styles
that were part of the starting project, there is a rule
that makes the button change its appearance
if it is inside of an element that has the liked class.
So with that, if I save that and reload this page,
we still don't see anything.
Well, we can't see anything here
because you must keep in mind
that the togglePostLikeStatus function here wants a post ID,
which it then forwards to update postLikedStatus.
However, at the moment,
I am using it as a action for this form.
And therefore what does it get?
It gets such a foreign data object, not the post ID.
Therefore, what we need to do here
and what NextJS and React allow us to do
is we must add some extra data that will be submitted
to that function when it's triggered by React.
And we can do this by calling the bind method
on that function object.
Now that's a standard Java script method.
You can call on function objects to,
you could say, pre-configure that function
to define some values that will be passed
to the function in the future when it's executed.
Bind then takes two arguments.
The first one defines
what the this keyword inside of this function will refer to.
And that doesn't matter to us here,
therefore I'll just set it to null.
But the second argument you pass to bind
will then become the new first argument
when that function is eventually executed in the future.
And in my case here, that should be the post ID.
So that's a way of pre-configuring which data will be passed
to this function in the future when it's executed by React.
Now if you would still need to get access to the form data,
you could still do that by simply accepting it
as a second argument here.
So any arguments you bind with help of the bind method
will be provided as first arguments,
and then the default arguments
which would've received otherwise will come thereafter.
But here, I don't need the form data,
so I'll just ignore it.
But with that, we'll now pass that post ID
to this togglePostLikeStatus Server Action.
And therefore now indeed
that user ID like combination should be stored.
So again, if you save everything and you reload,
if you click here, nothing happens.
But now if you reload the page,
this should be marked as liked, and this should prove
that indeed the user did like this item here.
It just doesn't update instantly.
The same is true for unliking it.
If I click this, which I did, it stays in that liked mode
until I reload.
And that's of course not the best user experience.
So what can we do about it?