Transcript
00:00 All right, so let's add our action. It's going to be very similar to our loader. It runs on the server, it accepts the params or these data function args. One of those args is the request, and then we can get the request data from the form data. So let's export a function called action. This will take our request,
00:19 and that's our data function args, and then we can get our form data from request or await request.formdata. This is all regular HTTP web fetch API stuff. So this form data object, you can learn all about it from MDN.
00:36 So if we open this up right here, boom, we've got request form data. So you can learn about the form data object and all of the really cool things that you can do with that, which is really nice, that we can just rely on the built-in behavior and standards that Remix is built on top of.
00:55 It's one of the things I like about Remix too, is that rather than wrapping APIs with something that they think is a little nicer, but it's definitely specific to Remix, they expose those APIs, taking whatever request is coming in and turning it into something that's web fetch, which I think is awesome.
01:13 So let's get our title. Yeah, you got to spell it right, otherwise I don't like it. We've got our title and our content, and then Marty the money bag is helping us use our database. So we'll move that up. We've got our params also, to know which note we're updating. So params and to get that note ID.
01:34 And then we're going to redirect the user back to the notes page. So we can return a redirect of slash notes, params, note ID. And then we're all set. So let's get rid of this, hit save. And now if I say exclamation point on that, we'll hit submit and we can't 404 not found.
01:54 Whoops, that's because my redirect is in the wrong place. So you actually can do a dot dot like this. So if I say submit right here, I get redirected back up to here. It's not quite working the way that you might hope it would work. And that's actually,
02:13 there are some interesting aspects to the way that relative redirects work. This is all platform stuff. This has nothing to do with Remix. So for that reason, I actually opt to always do full path redirects like this, just to avoid some of those kind of odd things with the web platform
02:31 and the way that it handles these relative redirects. So let's add the full path users, params, username, notes, params, note ID. So now if I come back here and we edit and get rid of those exclamation points, then hit submit, I go back to the page that I'm expecting to. Now, there's something
02:50 that I wanna call out specifically here that is really cool that you may not have noticed. If you've been building web apps in the era of the spa, or just like really client side heavy apps for a while, or for any time at all, and doing anything with mutations,
03:09 you probably noticed that we're missing something here. And it's a good thing that we're missing. The thing that we're missing is any logic in our code that says, hey, when you update a note, then you should update the note title over here as well. Now, if we go over to that component
03:28 that's responsible for rendering all those notes, those links, we'll see that it's just rendering the note title. There's nothing in here that says, when one of those things gets updated, let's go and update the list of notes. All of that happens automatically for you, just like it would if you were doing this
03:47 using the regular browser. So when the browser submits a form, it's gonna do a full page refresh. The form action is gonna do whatever it does on the server, and then it will send a redirect to say, okay, now you go over here. The browser says, oh, great, I'll go over there now. And it makes a request to go get that document.
04:06 And that document is going to be this page. So it'll render on the server and send back the HTML. It will always have the latest values because it's always going to run these database queries to get the latest stuff. So this is super cool because what Remix does is we're not doing the full page refresh, but it emulates the same behavior
04:25 by revalidating the data whenever you make a mutation. This is a fantastic default behavior because most of the time you do want the data to be revalidated when there's been a change in the database. And so that's why you don't ever have to think about keeping your data up to date whenever you do a mutation
04:44 because Remix will do it for you. Now, of course, there are some situations where you are loading a lot of data onto the page and that can be a performance problem or something. And Remix has APIs to opt out of this behavior for specific mutations. But as a default, this is exactly the sort of thing that we need in the front end world
05:03 to make it easier to do the right thing, to make the right thing be the default thing. And then you can optimize out of that. So the important thing for you to know is that when the user submits a form and that form has a method of post, that will go to your action.
05:21 And then when that action returns successfully, Remix will revalidate all of the data that's on the page. What that means is it's gonna call the loaders again and then feed that data back into your components. So you don't ever have to worry about this. Now, pending UI is something that you probably are gonna wanna think about
05:39 and we'll talk about that in a future exercise. Another thing that might be useful to mention as well is you can specify an action and you could say some other route and you'd have another file that follows our route convention and all of that. And that would have the action.
05:57 So by leaving off the action that just says, post to this action, to this routes action, and then you can add an action prop to the form if you want to send the user over to another route to handle that action. That can be useful, especially for things like third party auth
06:15 where you're like, let's go over to GitHub or whatever. So that is actions and I just think it's awesome. I hope you do too. I hope you enjoyed that one.