Current section: Server Actions 27 exercises
solution

Server Side

Loading solution

Transcript

00:00 Let's start this by going to our server app file here. And we're going to need this utility from React server DOM ESM server. This will allow us to decode the reply, to decode the body that is submitted by our client. So then we have this little refactoring happen for us.

00:18 So we've got our API that gets RSEs. Most of this is going to be shared by our action because we want to re-render the application and send that. So we're going to use this here in just a second. But let's start by making our request handler for the post body. And we got a little bit of help here

00:37 from Marty the money bag for handling our post request to slash action slash ship ID, which is optional. And then we've got our context right here. This context is going to contain a bunch of information about the request. Specifically, what we want is the server reference.

00:54 This is going to come off of the context.rec. That's our request.headers, or specifically we want the header called RSE action. And so now we've got our server reference. We, if you recall, the server reference includes the destination to the file with a hash pound sign

01:14 and then the export from the file. So let's split that. This is going to be our file path and the name will be the split version of our server reference. And now we can do a dynamic import to get the action. Whoops, const action equals await import the file path

01:34 with the name. And right around here is probably where you'd want to do some sort of check to make sure is this file path one of the files that we can let people just call on our server and let us import and all that stuff. So again, this is not optimized for that sort of thing, but hopefully you're still learning about RSEs in the process.

01:53 So now we have our action and yet you could do at least verifying that the action is a server reference. So when it says register a server reference, it's going to add the dollar dollar type of that you might've seen earlier. And so we can say if action dot dot dot type of

02:13 is not equal to a server reference, then we can send some JSON back or really we can just throw a new error. Invalid, valid action. And that'll be sufficient for what we're doing. So this will at least give us a little bit of protection. Okay, so with that now, now that we've got all that sorted,

02:32 we need to get the form data from the request that's coming in. So we're going to get our form data from await context rec dot form data. That's a regular HTTP request, fetch request. So we can get our form data off of that.

02:50 And then we need to turn this form data into the arguments that can be just passed into our action. So if we take a look at our actions here again, we need to call it with the previous state and the form data. So we can just use this utility from react server DOM ESM,

03:09 but that's what's happening is we need to turn the form data that's submitted to us into those arguments. So we'll get args from await decode reply, and we'll pass our form data and the module base path. So this is again, resolving where our location

03:28 of our files are relative to all of the other action and form data that we've got there. Okay, great. And so then, yeah, sure. Thanks AI assistant. So we want to get our results or our return value. We pass all of the arguments there. So this is where we're actually finally calling this function

03:49 with the previous state and the form data. And that, we'll just await that. And when that returns, then we'll send that back, not as context, but we want to send the rendered app. So we'll return await render app with the context, and we're gonna pass the return value as well. I don't need to pass it as an object.

04:08 We'll just update our render app to accept a return value. And then we're gonna change our payload to actually be root and return value, which means that we need to go to our UI index and update this right here to access the root property

04:29 because now we're sending an object that has a return value and a root. So we want to make sure that we're accessing the root property off of the content promise. Okay, great. And that saved there. We can refresh, and I can try Galaxy Cruiser exclamation point.

04:49 Exclamation point is there, and we get our success. And if I hit refresh, you'll notice we didn't revalidate this. We'll talk about that next. But if I hit refresh, Galaxy Cruiser, what, what? That's awesome. So we're in a good place there. So, and then if we were to put, try to edit it and hit enter,

05:09 then we're getting an error because the name, new name is the same as the old name. And so, yeah, that's looking great. If we try to get rid of this, of course we get client-side validation. So all of that stuff is working. We're sending the return value from our action right here. That return value goes into our edit text right here

05:30 where that form action is getting called. So that form state pipes down into our UI that we put together for the form message. And all of that piping is happening thanks to React. So if we were going to follow this all the way through, this form action, actually here, let's start from the beginning.

05:47 Let's go to our ship details right here. So we're importing this update ship name action from our actions. This is going to be not only action function itself, but it'll have a couple of properties tacked onto it thanks to our node loader. And so when our render to pipeable stream comes through

06:07 and it sees, oh, here's a client component, editable text. Oh, and you're passing this action function. I can't serialize that. So I'm going to access those properties that are on this update ship name function so I know how to serialize that. And then we can put that in the RSE payload. And then on the client side, as it's coming through here,

06:25 we pass this action, which is just a serialized action. We pass that into use action state. And so we have our form action. And when React calls the form action, it says, oh, you're calling a server component thing. So I'm going to go into your UI index. I'm going to go into your call server function,

06:44 and I'm going to pass it the ID of the action and the arguments, so the serialized form data. And we're going to allow you to do whatever you want to with it. And so what we want to do with it is call fetch slash action with all of the data. We go into our app inside of server,

07:01 and we handle that post request there. We're going to grab the server reference from the header, and now we know which file path and name we want for the action that's trying to be submitted. We double check that that is a proper server reference, so they're not just calling some random thing that we're not allowing people to call typically.

07:21 We get the form data. We decode that into the arguments that we want to actually pass to our action. And then we await the action with those arguments. We get that return value, and then render the app in response, including the return value,

07:38 so that once that call server is finished, coming back here, we get that return value. We return that from call server, and then React says, oh, great, so now this action that was called has a return value. That turns into the form state,

07:56 which gives us our status and our message. So that's the whole loop of what we have accomplished here so far. We're still not quite done, but that was the biggest piece that actually made things work together, and I hope that was interesting.