Routing to Controller 0:00Okay, so here's where we left off. We have all of our statuses, we have some dummy pages here, but now I'd like to add a form to add a new status that will submit an Ajax request to the server and then update our main feed here. So we have a number of things to do. I'm going to go a little bit more quick than usual. First, I'm going to go to my Laravel routes file and we're going to switch over to using a controller. So we'll grab all of this and then replace it with statuses-controller-at-index. And then next, I know I'm going to need an endpoint to create a new status. So if you post to that same URI, we're now going to hit statuses-controller-at-store. Okay, let's build that up with Laravel. Make a controller called statuses-controller, and I will pass the dash m flag so that I can give it the associated model, and that will just add extra boilerplate to save me some time. All right, so we can go toand I will pass the dash m flag so that I can give it the associated model, and that will just add extra boilerplate to save me some time. All right, so we can go to statuses-controller, and yeah, you'll see it uses it at the top, and then where relevant, we will type it. So let's go up to our index method and paste that in, and we can remove that. Okay, but next, what about when we want to add a status? All right, well, let's scroll down. That will hit our store method, and we need to do a couple of things. Well, one, you need to be authenticated, and we're going to dedicate a whole lesson to that. So we would need some kind of middleware applied here. But other than that, we would also need validation, create the status, and then finally return it and also include the user. Okay, so that means for validation, I'm assuming we'll have a form that will have one field, Storing Statuses Server-Side 1:27validation, create the status, and then finally return it and also include the user. Okay, so that means for validation, I'm assuming we'll have a form that will have one field, which will be the status. So let's say this, using the layer of L, let's validate the request, and specifically, the body of the status is required. Next, like I said, we'll do middleware in the next episode, but next, we have to create the status. So why don't we delegate to the user? Once we have authentication, I will just delegate to the currently signed in user, but until then, I'll just stub it out. Let's just find the user with an ID of one and assume that they are the one creating the status. I'm going to delegate to a statuses relationship that we'll create, and then we'll say create, and we'll say request only, and I'm sorry, it's called body. So it sounds like we need to create that statuses method. Let's go to user,create, and then we'll say create, and we'll say request only, and I'm sorry, it's called body. So it sounds like we need to create that statuses method. Let's go to user, statuses, and the relationship is a user can have many statuses. So has many status. Now, when we call create, it will assign the body, but it will also associate the user ID as needed. Finally, that's going to save to the user. Yeah, and we just need to return it and also include the user. So I say include the user, because in our JavaScript, we're going to accept the status, but I also want to be able to grab the name, like so. So if we don't load the user, we won't have access to the user relationship. So let's just say return status, but then using Eloquent, I'm going to load the user relationship. And you'll remember in our status model, we already set that up. So this is just basic Laravel and Eloquent stuff. If you're not familiar Creating Vue Form Component 3:09Eloquent, I'm going to load the user relationship. And you'll remember in our status model, we already set that up. So this is just basic Laravel and Eloquent stuff. If you're not familiar with Laravel, then it's okay. Just come along for the ride. I think at this point, we can switch back to our view anyways. So save it. This all looks good. And now I'm in my resources folder. Yeah, we'll go to the home view. And again, this corresponds to what you see right here. So for each of the statuses, display them. Okay, so now at the very bottom, we want to add another status. So what are we doing here? Something like add to stream form. So what we could do is hard code this form. But I know there's going to be behavior associated with the form, we have to submit an Ajax request. So one thing I often like to do is extract those into dedicated components, maybe something like this, add to stream. So now this component can be responsible for all of that.Ajax request. So one thing I often like to do is extract those into dedicated components, maybe something like this, add to stream. So now this component can be responsible for all of that. Let's put this, you know, you could have a forms folder or a general components folder, it really just depends upon how big your application is, and how you need to organize things. Components is fine. Add to stream dot view, that will consist of the template, and then also the script itself. Okay, but now, we want to reference this component, but the home dot view component knows nothing about it, we need to tell it, import, add to stream from, and then let's just go into our components folder and grab it. Now at the very top, I can say, this view has the following child components, add to stream. Okay, so if you want to try this out, and add to stream, we could just say,Now at the very top, I can say, this view has the following child components, add to stream. Okay, so if you want to try this out, and add to stream, we could just say, foobar. And actually, we do need a root element there, don't we, foobar. Anyways, I'm still using layer fill mix, so we can boot up our watcher. And we do see our component, but we lost the rest of our statuses. So server responded with 500. I must have made a mistake. Status controller, yep, I typed it in wrong. Let's go to routes web. Yep, status is controller. Alright, does that fix it all for us? It does. Alright, so we are referencing our child component, which means at this point, we can just build up the form like this. We're going to have another message wrapper. And then the message header will be something like push to the stream. That will be our terminology. And then what we need the message body as well.We're going to have another message wrapper. And then the message header will be something like push to the stream. That will be our terminology. And then what we need the message body as well. And this once again will be our form. So I think we just need a text area. So we'll call this status. And you know what, I don't even think we need a label. We'll say, I have something to say. Yeah, let's go back to Chrome. Scroll down. And there we go. But next, I need a submit button. So I have a little templates here to help me. Scroll down. And there we go. So now we need to say, well, when we submit this form to prevent the default action in the process, we'll call a method like on submit. Now add to stream, like I said earlier, can be entirely responsible for handling this form. So on submit, well, we want to submit an Antrex request, right? We could do this manually. But in the object-oriented forms lesson, we set up a nice abstraction for this, Adding Form Utilities 6:26handling this form. So on submit, well, we want to submit an Antrex request, right? We could do this manually. But in the object-oriented forms lesson, we set up a nice abstraction for this, right? So why don't we pull that into our project? I saved the source code up as view forms. It's not a npm package. I think somebody did create it. I can't remember who. I think somebody did take this and create a package that you can pull in. But I don't think we have to worry about it. I'm just going to grab all of this. And you'll see that we have the errors class and then also the form class. So let's grab errors. And we'll say resources assets JS. This could be part of core. Again, it could be part of forms or just a simple utilities. So there's our class. And then I will export that at the bottom. Next, we need, if we scroll down, we have our form class. So I'm going to grab all of that. Once again, resources, assets, JS, utilities, form, and then export that.export that at the bottom. Next, we need, if we scroll down, we have our form class. So I'm going to grab all of that. Once again, resources, assets, JS, utilities, form, and then export that. But there is one thing if I remember. Well, actually, real quick, let's scroll down. I think we had an alert, right? Yeah, that was just a temporary alert. But anyways, if we scroll back up to the top, you can see that we are pulling in errors. So I need to make sure that I import that. Okay, but next, it's true. Let's save that. It's true that we could import the form here. But for any project, you're going to reference that class everywhere. So I think a small smattering of globals is actually really, really useful. And it makes your workflow a lot more enjoyable. So let's go to my bootstrap class and import it. Utilities, form, and then I will assign it at the bottom,really useful. And it makes your workflow a lot more enjoyable. So let's go to my bootstrap class and import it. Utilities, form, and then I will assign it at the bottom, window.form, or any custom branded name you want. Okay, so now in our stream section, we can reference that data. And we will return our form. That will be a new instance of the form class. And once again, we just have the body. So I think that should do it. Let's take a look at how everything's shaping up. So if we go to our view section, yeah, we'll see add to stream does have the form, and we can see the body. So we just need to update our vmodel section on textarea. vmodel equals form.body. And by the way, if any of this feels kind of over your head, like you're not sure what's going on, go back and watch that three-part object-oriented forms lesson, and this should all make perfect sense to you. Anyways, let's go back. As I type into this,not sure what's going on, go back and watch that three-part object-oriented forms lesson, and this should all make perfect sense to you. Anyways, let's go back. As I type into this, you'll see that it does update. So now, you'll remember that the form class has a number of AJAX methods, like post, or put, or get, or patch, or delete. So when we submit that, you'll see that it defers to Axios, it references your URL, and then it grabs the data for the form. This should be everything we need. So let's scroll down to onSubmit, and we can say this.form.post to statuses. And maybe when we're done, we'll accept the new status, and we'll just say alert. All done. All right, let's go back to Chrome and give it a shot. So let's type some dummy text in, submit it, and whoops, we do get an error. User not found. Whoop, I thought we fixed that, did we not? I guess not. Let's import that, and then down here, yeah, we can update that.submit it, and whoops, we do get an error. User not found. Whoop, I thought we fixed that, did we not? I guess not. Let's import that, and then down here, yeah, we can update that. Okay, one more time. Submit it, and it fails again. Yeah, the stupid mass assignment exception. This is because Laravel is by default protecting us against mass assignment. Lots of ways around this, but let's just disable it. Okay, one more time. Submit, and there we go. It submits to the server. The server saves to the database. It returns the status while loading the user, so that means if I come back and give this a refresh, there's our text. So that part is working. The only remaining step is, as I type into this, I want to not require a refresh, but just automatically re-evaluate that list. Here's what we might do. When we're done, let's just omit an event, and we'll say we have completed this form submission, and we'll pass through the Emitting Event to Parent 10:33just automatically re-evaluate that list. Here's what we might do. When we're done, let's just omit an event, and we'll say we have completed this form submission, and we'll pass through the status. Now, this can be a nice and easy way to communicate back up to the parent, because what the parent can do, and remember, when I say parent, I mean the home view, and then add to stream is the child component. So the parent can say, well, I want to listen for once you've completed, and when you're done, we'll say add to stream. So I'm going to do something when you're done with your operation. So we scroll down, and we'll say methods, and actually, why don't we just say add status instead. Something like this, and all we're going to do is update this array. So I could say this.statuses.push status, and that will add it to the bottom, but in our case, we want to prepend it so it comes up first, so we can use unshift for that. So let's do that, and then maybe like a fancy flash message or anstatus, and that will add it to the bottom, but in our case, we want to prepend it so it comes up first, so we can use unshift for that. So let's do that, and then maybe like a fancy flash message or an alert. Your status has been added to the stream, and then just in case we're at the bottom of the page, why don't we just scroll back up to the top. You probably wouldn't have that in real life, but just to make sure the user is at the top of the page and does see their new status. Okay, so we can scroll up, update this, and does this all make sense? Most of this is a recap at this point. So add to stream performs an HX request, and when that is done successfully, we emit an event called completed or anything you want. You can name it however you need to, and we'll pass through the status. The parent is now saying, well, when you emit a completed event, I'm going to call an add status method myself, and here is where I'm going to respond to this event. And in this case, it's Handling Form Validation Errors 12:08status. The parent is now saying, well, when you emit a completed event, I'm going to call an add status method myself, and here is where I'm going to respond to this event. And in this case, it's going to update the statuses array that will trigger the reactivity, and it will refresh. So we come down, add a new status, submit. There we go. We go back to the top, we alert, we update the database, and there we go. It's all working. So at this point, what if we try to submit the form and there were errors? We need to allow for that, and we've already learned about this once again in that object-oriented forms lesson. We could say span help, and we'll use is danger here, and we're going to say the text will be the form errors, and we'll get any errors we have for the body. But also, we don't want to display this at all unless there are errors. So I could say form.errors.has anything for the body. And let's make sure we close out that text area. Yeah, does that allBut also, we don't want to display this at all unless there are errors. So I could say form.errors.has anything for the body. And let's make sure we close out that text area. Yeah, does that all make sense? So we have a form to echo out the error, if we have any at all. Let's come back to Chrome, try to submit it, and there we go. We get our error. But maybe we should disable the submit button. So we could say disabled equals, do we have any errors at all? So let's switch back, we submit it, and now you can see the button is disabled. But as I type into it, I want it to re-evaluate. So if we scroll up, we could say when you key down or key up, we're just going to say form.errors and make sure we clear them out. All right, so now submit, it's disabled, but as I type, it re-evaluates and it removes the errors so that we can submit again. Get our alert, scroll to the top, and refresh our message. And now on every subsequent page load,it re-evaluates and it removes the errors so that we can submit again. Get our alert, scroll to the top, and refresh our message. And now on every subsequent page load, of course, we'll see that. All right, and that'll do it for this episode. So good job.