Next.js Fundamentals, v4

Editing Issues with Server Actions

Scott Moss
Superfilter AI
Next.js Fundamentals, v4

Lesson Description

The "Editing Issues with Server Actions" Lesson is part of the full, Next.js Fundamentals, v4 course featured in this preview video. Here's what you'd learn in this lesson:

Scott walks through implementing the edit and delete features, explaining how to update issues and delete them using server actions and parameters. He also clarifies that the return type for server actions is flexible and not constrained by Next.js.

Preview
Close

Transcript from the "Editing Issues with Server Actions" Lesson

[00:00:00]
>> Scott Moss: We left off on creating new issues with our mode, our linear app. So I'm going to go ahead and start that right quick run dev. There we go, make sure that's not broken, cool. Okay, so what we want to do now is start working on the edit and delete feature so we can edit these things right now.

[00:00:31]
We can't do that, so let's do that, it's mostly more of the same. There is a difference, and I was kind of hinting at it in the previous session, where we can do server actions without a use action state hook and without a form. So we'll be doing that and then we'll be talking about like how to get the parameters out of the ID and things like that, or get the ID out of the parameters.

[00:00:52]
Okay, so let's look at the notes for that, cool. So editing and deleting an issue, like I said, it's mostly the same. So our objective here is one, we got to go fill out the update issue function. So we can go make that, it's nothing really new here.

[00:01:12]
It's just doing another validation on the form because you can update every single field on an issue. So pretty much the same thing. And then the delete issue is even simpler because it's not a form, it's just pressing a button and deleting it. So the actions are pretty simple, the thing that's different here is when we go edit and delete using the actual uI and you'll see that we're using params here.

[00:01:39]
So we'll talk about that and how that works. And then we'll also talk about how to actually like call server actions and things like that from using a transition and not just a hook, the form hook. So no, don't want password, okay, so let's do it. Let's start with adding our update issue stuff to our action.

[00:02:01]
So we can do that by going over to our repo, going to the issues page inside the actions folder. Let me just close everything, there we go. And then I already have this function kind of scoped out here, but it's just vanilla. We did that, so it was breaking trying to import it.

[00:02:19]
So I'm just going to grab that, pretty simple. So the first thing we want to do is we want to get the actual data for the issue because we're going to be updating the issue and it's a form, so we're going to. It's going to be like partial data because you might update some fields, you might Update, other fields, it's not always going to be a complete issue in which you're updating.

[00:02:38]
So it's going to be a partial issue, essentially, so we want to do that. And then the ID in which you want to update on. So we'll get the ID which is a number and then partial for all the typescript people, or I'm sorry, let me just get this right here, called data.

[00:02:55]
And then partial is something that's built in a typescript and you could pass in, whatever type you want. In this case we have issue data, so we'll pass that in like that. And partial just means if there's anything on this object that's required, as far as TypeScript goes, or anything on this type that is required, it is now not required.

[00:03:24]
That's basically all it is, from there we want to get the current user, if not the user, do the same thing, validate our schema. You guys know the drill at this point, so let's just get warmed up. So we'll say user equals await, get current user like that.

[00:03:44]
If not a user, we want to return success, false message. You can put whatever you want here, say unauthorized authorized access and then add an error message to say authorize, cool. If there is a user, we want to go ahead and validate that schema, so we can do that using the Zod schema.

[00:04:16]
The issue schema will make it a partial one. Just because again, this, because you're doing an update, we don't know what fields you're updating. So we're not gonna follow the same requirements as like for instance, on the database. It might be a requirement on database level that you must have an issue name or something like that.

[00:04:35]
But that doesn't mean when you do an update, you have to update the name of the issue, maybe you only updated the description. So we don't wanna follow the database schema, which is where this issue data is coming from, we wanna make that a partial. So we'll just say the update schema is the same thing as the input schema or issue schema, sorry, partial, like that.

[00:05:03]
And then once you have that, then we can do a safe parse. We'll say validation result equals update schema, safeparse of the data. Then we can say, if not validation result success, we're going to do something very similar to this. But in this case it's not unauthorized, it's just invalid issue or whatever, you want to put here.

[00:05:37]
And then we can take those error messages from Zod and just flatten them and show them. So validation error, flatten filled errors, cool. And the rest of the stuff is pretty not that important. It just really comes down to the business logic of going through each single one of these.

[00:06:06]
And making sure that like you have at least one of these things here that you're trying to update and informing that object. So you can just copy that and then just put this into the update, it's not that big of a deal. It's definitely a cleaner way to do that, but we'll just do it like that.

[00:06:23]
And then lastly, success, true, yeah, that. Then you can put whatever message you want. So in this case, issue updated successfully, there you go, we'll wrap this in a Try Catch. I always forget to just do that at the beginning because normally I don't use Try Catch. I actually use like this utility function that returns an array and it's either the value or an error because I hate doing Try Catch because it's just ugly.

[00:07:04]
So not used to doing it all the time. Also, I think JavaScript is, there's a proposal in JavaScript to do the same thing with a special syntax. So really looking forward to that, okay? And then, yeah, for the error, you can just do whatever you want, for the error, return whatever you want.

[00:07:20]
>> Student: So I'm seeing in the notes that you have the return type for this whole function as promise of action response, if it's not action response, would that. I guess, like, is that what Next JS is expecting, like an action response or can you return anything?
>> Scott Moss: Good question, you can return whatever you want.

[00:07:50]
This is just a payload shape that I came up with, yeah. So it makes no constraints on what you return, it's totally up to you. Because when you use this inside of the use action state hook, you do whatever you want in that function, okay?
>> Student: So action response isn't just, you came up with that?

[00:08:08]
>> Scott Moss: Yeah, I can.
>> Student: Okay.
>> Scott Moss: Yeah, yeah, the types of-
>> Student: I thought maybe that was like a Next JS.
>> Scott Moss: No, yeah, it's right here, nope, I just made it right here. Yeah, you can do whatever you want, yeah, yeah, they're pretty flexible. I can't think of too many places in next JS where you have to return something a certain way other than like, I don't know the route handlers.

[00:08:35]
But that's with any server you have to default export a component for a page. That's it, everything else, you can do whatever you want, they don't really make any, any constraints on that. So, okay, let's the delete one, we can just copy that one. It's pretty straightforward, but just to walk through it, it's gonna get the current user, it's not the user, get out of here, you can't delete anything.

[00:09:03]
If the user is there, go ahead and delete it by the issue id. Although realistically you should be checking and make sure this user is deleting an issue that belongs to them, but that's okay. We're going to take shortcuts and then, yeah, send back whatever you want.
>> Student: I know this is just like a, like a nitpick quote unquote, but is it, is it easy just to do like.

[00:09:28]
Or would it make sense to do a, like a 403 forbidden or something here?
>> Scott Moss: That's a good question, so think about the context in which this action. Well, so the question was, would it make sense to do a 403 for bid in here? Think about the context in which this function is called, this is a server action.

[00:09:50]
So chances are it's gonna be called on some user interaction on the client and not during a HTTP request to get a page. So if you are, I don't know, clicking a button, clicking a form and something wrong happened, what would you. And let's say you were making the API request, what would you send back on the API request?

[00:10:17]
If in this case 403 is forbidden, would you send back the 403 so the client can look at that, or would you not.
>> Student: Send Back A 403?
>> Scott Moss: That was a trick question, yeah, you would, you would send back the 403. But then if you look at other things like GraphQL, where there's always a 200 no matter what.

[00:10:36]
Right, so what next JS is doing here is because this function has no idea how it's going to be used. It doesn't know that it's going to be, it doesn't know that it's going to be on a form action. It doesn't know if it's going to be in a use transition, it just knows that it's just going to be running on a server, it's a server action.

[00:10:56]
So it has access to the request, but it has no idea what it's going to do there. And you don't get access to the low level request object through these server actions, it's abstracted away from you. You just get access to the payloads, the inputs and the outputs.

[00:11:11]
So the reason I bring up GraphQL is because it's kind of operating similar to that. Whatever you want to show the client as far as, like, status codes or whatever, you can just do that here through the mechanisms of the data. But not through the raw implementation of the HTTP request, because you won't have access to that through the client.

[00:11:32]
>> Student: Okay, could you get that with, like, middleware and Next js, or could you get that with middleware?
>> Scott Moss: I don't think so, we are gonna talk about middle. Are you talking about, like, the middleware that Next JS has or some other type of middleware?
>> Student: Just any kind, yeah, anything to intercept the requests.

[00:11:48]
>> Scott Moss: To my knowledge, Next JS does not have a mechanism to intercept the request for server action.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Start a 7-Day Free Trial