HTMX & Go with ThePrimeagen | Preview

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC] Hi, my name is ThePrimeagen. I am a senior software engineer at Netflix, husband to a beautiful wife and a father of four. The reason why I created the introduction to HTMX is it's one of the few technologies I'm very excited about and I believe it has a long future ahead of it. In this course, we go over each of the basic annotations of HTML and then after that we go over some advanced patterns that make developing apps easy. First thing is HATEOAS. You've probably seen this term, heard this term. It stands for Hypermedia As The Engine of Application State, meaning the state of your HTML is the state of your program and that is how we drive the changes further on down the line is what is currently there. In the modern world, we don't do that. What we do in the modern world is that we have the virtual DOM, usually contains the state of your program. Then you have a secondary state, which is all the closures and things within your JavaScript. The use states, all the little bits that are going to update that virtual DOM, that's your second layer of state. Then typically if you're more enterprise, you'll have a third layer state, which is your Redux state, which is controlling your routes. It could be controlling how you're getting data, async, reducers, selectors, all that fun stuff to just simply drive the engine of state. And so in the HTMX world, we try to make it simple, the hypermedia, the HTML, that's the engine of the engine of application state, not all the other things, all the other layers. It's your server as the truth. Your client is the reflection of the truth. And there's little in between. Now you can go as much as you want. I've seen projects where they use HTMX for all the chrome and all the stuff around the application and they use React inside of it to drive all the user interactions. Totally reasonable, you can emit events from within a React application and have HTMX actually run on the outside and do all the updating and executing on the outside. So totally okay. Does that mean HTML is finally a programming yet language, yes. Does that mean you're finally an HTML engineer, absolutely. What a great day to be alive. Finally, also, this is a 2011 nice little document which you should read. This is by the current community manager of Rust, and he has a whole talk about how to do HATEOAS and all this stuff even in 2011. Again, this concept's been around for quite some time, this is not something new. It just feels new because some unhinged Montana man has now made it popular. And by the way, I'm not the unhinged Montana man. All right, so let's do this. Hopefully I have the exact link, yes, I do, fantastic. So typically, this is kind of like your standard server interaction. I do a get at the root and the server responds with some HTML that has links off to JavaScript. Maybe it's not a server that actually does it. Maybe it's like a CDN in front of the server, whatever happens. Something happens and you get HTML back, right? And so, typically, we're going to be doing something like this with HTMX. Any element may have some sort of hx-VERB. That VERB will have a path. We will make a VERB request to that path. It will hit the server. The server's expectation is to respond with HTML. The contents of the HTML will replace the inner HTML of the element that made or that initiated the request. And that is only if it responds with a 200. So if you respond with a 400, a 500, or whatever, you now have to define some sort of custom behavior. HTMX just says, no, we're not gonna do anything in the 4 to 500s. So, that means if we had a div that posted to foo, and it had the contents of four green squares, and the server responds with two blue squares, the final state will look something like this. The div will now have two blue squares. HTMX does emit a lot of events. So you can hook in with JavaScript if you want to add custom behavior. It can react on a lot of different things, including custom events. It has ways to reduce HTML from the request so you don't actually get the entire request. You can just select out parts you want. And it also has ways to redirect to the HTML to other parts of your application. So this is all a part of it. And you can even redirect from the server or you can redirect from the client. You can make the choice yourself, depending on where and how you do it. All right, so pretty fantastic. Hopefully everyone, that's it. I just taught you pretty much all of HTMX right now. So we're gonna kind of go through some exercises and put this into practice. I just really want you to see this image right here. This I think is the best image to understand HTMX. It starts with some green squares inside of it. You make a request, server responds with blue squares. Now you have blue squares inside of that same div. The div was not removed, the insides were removed. So there we go. We have this nice little post. When we make a post, this is what happens to our context page. This kind of sucks. Can we all agree that this sucks? This is not what I want to see at all, right? This is not it. This is not it at any of it. In fact, this is horrible. And if I keep on adding, it'll just keep on getting worse and worse and worse and worse and look at that thing go. It's just awful, right? So this isn't beautiful. I bet you though, that a lot of people can now guess what happened. What happened? >> I have no idea. >> You have no idea but we have already solved this problem. >> We're not targeting the div. >> Say it out loud, come on. >> We're not targeting the div. >> Yeah, we're not targeting the right content. I love it. I know, right, John? >> Yes. >> I knew you were gonna get it correct. I could feel it. You were ready. You were just there. All right, so yeah that's exactly it. Look at our response. We're responding with the whole darn thing. And what is it doing? Who made the request in this situation? The form made the request. So therefore the form gets replaced. I mean, if we go to the HTML, we might see that our form has a form, that has a form, that has a form, that has a form. Our forms had babies. Look at that. Look at how many it had. So we did something wrong here, right? We're need to start targeting and thinking about how are we gonna update this page. And this is actually quite an interesting problem. We're gonna get to the problem of form and display all in one page. Let's see, I don't know what it says. Yeah, so let's fix this problem. So this is the same problem as before. We're returning the whole thing. So first and obvious and easiest thing we can do if you're lazy and you just want to get a product out there, just hit it with the old hx-target = body. My goodness, fantastic. I'm refreshing the page. Did you see how fast that compiles? My goodness. It's just like it's the easiest thing ever. Look at that. We're just adding stuff, it's updating, not a big deal, super, super simple. By the way, I just love how fast that, the compilation is just so good. All right, is this good? What are some problems with this approach? Can someone give me a problem with what we're doing right now, John? >> Are we sending the full HTML? >> We're sending all the contacts and everything. >> The payload get bigger, the more trips that happen. >> Yes, so if you couldn't hear it, the payload keeps getting ever bigger. Meaning if you had a 1,000 contacts, we have to send down 1,000 contacts plus a form every single time you add one. That's a horrible problem to be in, we don't wanna be there. So we're gonna explore the space, just a little bit, okay? We're just gonna get in there, we're gonna see what happens because this seems kind of exciting. Yes, I know some people are suggesting the fix being Rust, 1,000 contacts, not a big deal with Rust, right? It's still a problem. Trust me, this is a problem. Let's not do that. So let's first start by only responding with contacts. That should be a pretty easy reduction of stuff. So let's jump back in here and we need to change two things. We need to change, who are we targeting and then the code that's being generated. So I'm gonna go like this, hx-target, and let's go down here and call this thing id = contacts, right? And then we're gonna jump back here and we're gonna go #contacts. All right, awesome. So now that we have that, that should do all the redirecting. So now we're gonna go over to the server and we need to say, hey, don't render the index, render the context, right? Or wait, I think I call it display. Did I call it display? Yeah, I called it display. Terrible name, but you get the idea. Okay, awesome. We are gonna do that. So I'm going to refresh this. And let's add a contact. Okay, I mean, that's better, right? We're getting better. I'm gonna just keep on. Look, I'm just creating so many sweet contacts. Is this better? In some sense it's better, but let's take a little gander at what's happening inside. Look at what happened here, we were having multiple levels of contacts. Why is that? Can anyone tell me why we're having multiple levels of contacts? >> InnerHTML. >> InnerHTML, boom. Did you know HTMX you can say how you want to replace it. So let's just jump up here and let's do a little hx-swap = outerHTML. So instead of replacing the inner contents, let's replace the entire element here for a second. So let's at least fix that problem. So I'm gonna do that. And boom as we added a bunch, notice that we no longer have that problem. So we can kind of specify how we wish to swap out the elements, which is a pretty cool little items. So for those that didn't see it on the form, I did hx-swap. And so this is just how you dynamically say, this is how we want to change things out. Pretty cool, pretty great. Very happy about that. I'm happy, you're happy, hopefully let's keep being happy together. So now we have this delicious icon right here. Next, we need to make a do a delete to the icons id, or I mean, well, we need to make it do a request to contacts id. Obviously, you probably go we don't have ids for contacts. Well, we're gonna have to make one, okay? We have to make one now. All right, so let's go hx-delete. This delete attribute call will cause an element to issue a delete request. Okay, fantastic. Let's absolutely do that. And let's go to contacts. And then we'll do a /.id. Yeah, look at that. Looks good, right? It's looking good. This is feeling good. And then I'm gonna also do a little id up here and call this contact. And then we're gonna put an id on this one. This is for a future problem that we will see. We'll get there, don't worry about it, it's okay. So we have this nice delete. So now how do we say what to delete? Because if I just issue this request and we successfully delete, what is HTMX gonna remove? >> It should remove the HTML connected to that contact. >> It will remove, currently, the savage inside of this div, right? Because it always the default behavior is swap innerHTML. So we need to have a different swap potential strategy. So let's first have hx-swap = "outerHTML". So now we will delete this div, but we're still only deleting the trash can. So we need to do something a little bit different. Let's also add in hx-target =, so normally if you can you can use something called closest which is a CSS which does a selector upwards and will check your ancestor. So technically you could do something like this except for I am a div myself therefore closest will also consider yourself as part of the selector thing that's just welcome to Web 3 delicious standards here, very annoying. I wish it just did parent and beyond because that'd be super useful. Cuz I could just say, hey, delete my parent div and it would just boom. And it would work. So we can't do that. So I'll just go like this. Contact, do you like how it does that little shift every time? I don't know what that is. There we go. So fantastic. So now we're saying, hey, who to delete? How to delete it? What end point to get to go to? I think we're effectively ready. Let's do a little refresh. It says internal error. Why does it say an internal error? Anybody, anyone wanna make a guess? >> No id. >> No id, bam. Gosh, this guy, it's like you program Go. It's just like you know, you know it, you could feel it. All right, so I'm gonna go up to my little contact form and I'm just gonna go var id = 0. Why not? This is why, by the way, if you're wondering why I did a little new contact here, it's like I was pre-prepared for this eventuality we're having right here. So there we go. Okay, there we go. Everything's been specified. We're looking good. Fantastic, I don't think I technically need this one. Yeah, I don't even need it. All right, so there we go. Awesome, so now we have an Id on the contact forms, which means every single time we create a contact, it will come with an Id. Which is also why I use these functions right here. So now even our dummy data, we have Ids, we're feeling good, everything's looking good. We go back here, we hit refresh, everything's there. Let's look at the HTML just to validate that we have actually done the thing. Let's bring it down, look at that. We have contact 1 reflecting on the kids. This thing is saying, hey, target contact 1 swap outerHTML. So if I click it, let's bring up the old network and I click that look at what happened. It said, hey, that's not found, why not? Well, we did a 404 because there's nothing there. We haven't added the handler yet, but it did the right thing. It went to contact/1 and issued a delete request. It's like proper. We're just so proper at this point. So let's do an e.DELETE/contacts/:id, fantastic. Let's get the id string equals that. I'll do id and err equals stir convert. I mean, maybe I could have done something better here, but I didn't do something better here. Throw in one of those. If we hit that, I'm just gonna return a e.String(400, right? Is that no, it's C, sorry, C.String. So we're gonna go all the way back up to the data and let's add in one more function. Function d Data, let's go indexOf this. And we'll do, let' see, what do we wanna do? We want to do id, right? So there we go, so we're just gonna return out the contact. I mean, we could make it nice like that. And copilot will pretty much do it for us. All right, awesome. And we don't wanna do that, actually, we wanna do it indexOf, don't we? Let's return out the index that was found here. Or -1, I guess we can do the other way. I'm not sure why I did an index 1. Why did I do an index 1? Did I do it? Do I have a good reason for it? I don't think I have a good reason for it. Index 1, it's just in my head, that's what I was doing. So we're gonna keep on doing the thing I already built. And we could actually do, yeah, we could have just used the nil as that. Else, we need to simply delete out this. That's why I did that. That's why I had to delete it out. That's the thing we got to do. And I knew it and so let's just do the little deletion here. All right, fantastic. Let's just make sure this is good. We're gonna have page up to index and then we're gonna start from index +1 and on. Okay, awesome. We've now created this wonderful contacts right here or we've updated our contacts. Now we need to return something from this deletion, which of course, C.NoContent (200), right? We're just gonna return an empty reply. You got it. So I'm gonna refresh this and when I hit delete, it's gone. Look at that inline deleting, refresh, nothing is there. Hit the save on the server, we're back. We just rehydrated the data, okay. [MUSIC]
Info
Channel: Frontend Masters
Views: 148,354
Rating: undefined out of 5
Keywords: #HTMX, #Go, #ThePrimeagen, #FrontendMasters
Id: SZ0nR3QHebM
Channel Id: undefined
Length: 15min 58sec (958 seconds)
Published: Thu Feb 01 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.