مرور راهاندازی یک رفت و برگشت به سرور0:35
to do with that data and send the response back. Okay, so we have the snapshot all ready. Now the next thing to do is to listen for a click on this plus, so let's do that. We can get the current element, so this is the root element of this component, so take a look at this, this div wire:snapshot, this root element. Let's get that, and let's listen for a click on that. Let's say, l.addEventListener(click, okay? And then we'll get the event object, which I'm just going to call e, that's the parameter, that every time there's a click inside of this element, this event object is going to get passed to this callback, so let's just alert('you clicked me'), okay?
that every time there's a click inside of this element, this event object is going to get passed to this callback, so let's just alert, you clicked me, okay? And we don't have to console log this anymore, and while we're here, let's just clean this up a little bit, because we have some comments left over, okay? Now if I click anywhere in this component, hey, you clicked me, cool, but we don't just want to listen for clicks anywhere in the component, let's open up the component. We are listening for wire:click, clicks on a button that has wire:click on it, so there's a few different ways to do this. You can see we're adding the click listener to the root element, and you might ask, well, why don't we look for all elements with wire:click, you know, using querySelectorAll
Using Event Delegation1:41
You can see we're adding the click listener to the root element, and you might ask, well, why don't we look for all elements with wire:click, you know, using querySelectorAll or something, and then add individual event listeners to each of those buttons. And the answer is, that's one way to do it, and that's actually much closer to how Livewire actually works, but to keep things simple, we're going to use this concept called event delegation, which is a fancy word for a simple thing, where because, like, browsers work a specific way, where if I click this button, the click event bubbles up. It'll start here at the button, and then it'll bubble up to the div. We can listen for a click on the root div, so we only need one listener, and then we can decide what we want to do with it.
We can listen for a click on the root div, so we only need one listener, and then we can decide what we want to do with it. We can decide, hey, did that click originate on something with wire:click? Okay, then let's do something. It's just a simpler way, because we're only registering one simple listener on the root of the div, and then we can do whatever we want, so that's the approach that we're going to take. Okay, so let's do that. We're adding the event listener click, but right now, again, it's listening for clicks anywhere inside of this component.
Filtering wire:click Targets2:37
We're adding the event listener click, but right now, again, it's listening for clicks anywhere inside of this component. We want to scope it down to only clicks that originated on a wire:click button, so let's do that. Let's say, if the e.target, now what is e.target? Well, let me just show you. If we console.log e.target, and then click on stuff, okay, we click on this, all right, that was a click on a div, on the counter div. We click on the zero, that was the span. If I click on the plus, that was the button, so event.target is always the element that
We click on the zero, that was the span. If I click on the plus, that was the button, so event.target is always the element that the click originated from, so we can say, okay, if e.target.hasAttribute('wire:click'), then we know we want to do something with it, and we could do this and do all our stuff, but I would rather handle the opposite case. If it doesn't have wire:click, just return out of this function entirely, so that now we can just work with a button here, and so this is called a guard clause, where rather than doing an if statement and doing everything inside of it, we're going to look for the exception up front, and just return out, so that anything that happens below here, we know we're working with the right button.
Sending Requests via Fetch3:37
exception up front, and just return out, so that anything that happens below here, we know we're working with the right button. Okay, so we have our button. It's time to send a request to the server, so we're going to use the fetch API. This is a function that just exists in browsers. We don't need to install any package for it, and we'll pass it a URL. We're going to have to create this endpoint. We haven't done this at all, but we're going to create a URL called Livewire that's going to handle all of these Livewire requests. Now we can specify the payload that we want to send over.
to handle all of these Livewire requests. Now we can specify the payload that we want to send over. We know that the method should be post, that's what we're going to use, and then we also know that we need a header, so this is headers, okay, and this is like fetch. It's nice, but it's a little bit verbose, like if you're used to something like Axios, you can just say axios.post, specify the URL, and then some payload parameters. Fetch is a little more complex, but I want to use something, I want to keep the overhead pretty low, and I use fetch in Livewire itself, because fetch is great. You just, I don't know, it's a little bit more verbose, so one header that we need to send that usually gets sent automatically with other tools is content-type: application
You just, I don't know, it's a little bit more verbose, so one header that we need to send that usually gets sent automatically with other tools is Content-Type: application/json. We just need to tell the server that this is going to be a JSON request. Okay, and now we can specify the body, and this is going to be where we have something like snapshot, whatever, but it's still, it's a little bit gnarly. It's not as nice as just being able to do that. fetch expects us to send a body string of JSON, so we have to actually JSON.stringify, isn't that a funny name, stringify, but this is the inverse of JSON.parse. Remember JSON.parse up here, where we're taking a string and we're turning it into
that a funny name, stringify, but this is the inverse of parse. Remember JSON.parse up here, where we're taking a string and we're turning it into an object? Well, JSON.stringify is the inverse, where we take an object, which we'll fill out in a minute, and it'll turn it into a string and put it into body. So for now, let's just send foobar to the server, and we can get the server wired up to receive, you know, foobar and send it back and make sure that we're all good. All right, let's just make sure that this thing gets sent. So let's open up network, and we have fetch XHR request, so we're just filtering these requests by fetch requests.
Creating Livewire Route5:29
So let's open up network, and we have fetch XHR request, so we're just filtering these requests by fetch requests. Hit this plus. Okay, and there we go. We sent a fetch request to an endpoint, that Livewire endpoint, and we got a 404 back because it doesn't exist yet. So let's implement that endpoint. Let's open up our routes file in this other tab, and we'll create Route::post Livewire. Okay, and then our function, that's going to be our handler. All right, now in here, let's just return request()->all() back, so that whatever we send
Okay, and then our function, that's going to be our handler. All right, now in here, let's just return request all back, so that whatever we send to the server, we're just going to send back and that'll kind of tell us that that everything works. All right, let's try this. Now, we hit this plus button. And okay, we got a little bit farther, the endpoint exists now, but we got a 419. The 419 is page expired. Now this is a little bit deeper, and I don't want to dive too deep into it. But by default in Laravel, every AJAX request you send, you have to send a CSRF token.
Bypassing CSRF Protection6:17
Now this is a little bit deeper, and I don't want to dive too deep into it. But by default in Laravel, every AJAX request you send, you have to send a CSRF token. And it's a way to prevent cross site request forgery, blah, blah, blah security stuff. And yeah, so we could do that. We could get a CSRF token into here. And in real Livewire, we do do that. But for our purposes, we're not going to deal with any of that stuff. We're just going to bypass it. So let's go into our app folder in the HTTP kernel. So these are all middlewares that get applied to every single request that comes through.
So let's go into our app folder in the Http\Kernel.php. So these are all middlewares that get applied to every single request that comes through to Laravel. And there's this one called where is it? It's verifyCsrfToken. If we click through to that, we can add exceptions to this.
It's verify CSRF token. If we click through to that, we can add exceptions to this. So we're going to say, hey, this Livewire endpoint, don't do any security stuff. We know what we're doing, whatever. Yeah, so that's what we're going to do. Again, in a real context, we wouldn't punch a hole in the security wall like that. But we're doing that. All right, let's try this plus. And there we go. We have a 200.
Right? Well, of course, we probably want to send that snapshot that we have to tell the server about the component we want to deal with. So we can do that. We'll say snap, we'll make the key snapshot, and then the value snapshot. And let's, let's just dd this here so that we can, I don't know, see that we're getting it back. request. snapshot. Okay.
Snapshot. Okay. Great. We're going to dd that. Send over snapshot, open up the dev tools, hit this plus, and check out what we got. Okay. We got a 500. Why did we get a 500? Oh, because we just dd and I think dd just returns a 500. But you can see the results of that are what we want.
Oh, because we just dd and I think dd just returns a 500. But you can see the results of that are what we want. We have our snapshot into php. One little quick JavaScript tip. If you have a key and a value that are exactly the same in an object, you can just use one of them and Livewire will, or sorry, not Livewire, JavaScript will implicitly know that this is both the key and the value variables. That's just a nice little shorthand. All right. So we have the snapshot going through, but we're missing a big component.
Passing Method to Server8:25
All right. So we have the snapshot going through, but we're missing a big component. We're missing the thing we actually want to do, where we have that button with wire:click increment. We need to send that we want to call increment back to the server. So let's do that. In JavaScript, we're going to have to get the method that we want to call on the component. And we'll do that with e.target. That's going to get us our button element and we'll say getAttribute wire:click. Kind of like we did before with getAttribute wire:snapshot, except this time we don't have
That's going to get us our button element and we'll say getAttribute wire:click. Kind of like we did before with getAttribute wire:snapshot, except this time we don't have to do anything fancy. This is just going to return to us. Let's alert that and just see it. So it's going to return to us whatever we pass in a wire:click. So hit this plus, and there we go. We have increment. Now we can pass that to the server. We could say in addition to the snapshot, the server also needs to know what to do.
Now we can pass that to the server. We could say in addition to the snapshot, the server also needs to know what to do. We'll say, hey, call the method if we can type it with our keyboard. Okay. Call the method and then pass through the method. And now instead of dd-ing snapshot, we'll dd call method, hit the plus, and we still have that alert in there. And there we go. Increment. So we now have everything we need on the server side.
