Create AddComment component0:00
Okay, let's go ahead and work on adding comments. Before we do that, let me quickly fix this line clamp here, which I still have, and obviously we don't need in here. So let's get rid of this line clamp, okay. And now let's go ahead and make a new component for adding comments. So we already have the UI in place, you can see here. So let's do that. So php artisan make:livewire, I'm going to call it AddComment, but you can also name it CreateComment or PostComment, whatever you like, okay. And let's go ahead and go to that, AddComment.
you can also name it CreateComment or PostComment, whatever you like, okay. And let's go ahead and go to that, AddComment. Actually, let's grab what we have in our idea show. So I believe that's where this code lives. So let's look for a reply here. There it is. So I'm going to move this entire thing into that component. So that would be this entire div here. Okay, let's cut that out. Let's say Livewire, AddComment.
Okay, let's cut that out. Let's say Livewire, AddComment. And we do need an Idea to be passed in, just so we know which Idea to attach to the comment that's being posted. So let's pass in that idea, like we've been doing. Actually, we only need the idea idea, but I'll just pass in the entire idea. Okay, let's go to that AddComment. Let's paste that in. Make sure to re-indent here. Okay, and let's do the same thing we did for Idea comments and just pass in the idea.
Show form only for auth1:39
Make sure to re-indent here. Okay, and let's do the same thing we did for IdeaComment and just pass in the Idea. Okay, let's grab this. It's still highlighted for me, which is great. Just paste that in here. And let's accept the Idea or import the Idea. Okay, so this should still render the same when I refresh. It does. Okay, now I want to render this form only when we're logged in and show a login or sign up button when we're not logged in.
Okay, now I want to render this form only when we're logged in and show a login or sign up button when we're not logged in. So let's work on that. So right now I'm not logged in. So let's add those buttons in here. So let's go to AddComment. So I only want the form to post the comment to render if we're logged in. So we can use the @auth directive here. Okay, let's go ahead and indent that and @auth here. And we can have an @else case as well.
Okay, let's go ahead and indent that and auth here. And we can have an else case as well. So this is where the buttons go if we're not logged in. So let's say px-4, py-6. And let's put a message in here. Let's say font-normal, please log in or create an account to post a comment. Okay. And here we can have the buttons. So let's add a new container. Let's make a flex items-center, give it some space in between space-x-3 is what I have and
Add binding and validation4:28
So now we're logged in. So the form should show up and it does. So let's add a wire:model on this text area for the comment. So where's the text area here? There it is. Let's add a wire:model on it and I'm going to name it comment. And let's go ahead and work on that component. So AddComment. Let's add that new field for the comment that the User types in. And let's go ahead and do validation as well.
Let's add that new field for the comment that the user types in. And let's go ahead and do validation as well. So we can say protected $rules equals comment. And we just want to make sure it's required. And it's a minimum of four characters. Okay. And let's go ahead and make a new method here to handle the form submission. Let's call it addComment. addComment. Okay.
Add comment. Okay. And this is the authorization. So it's pretty much the same as what we've been doing. And in this case, we just want to make sure that the User is logged in. So let's just grab it from here. Paste that in. Okay. And it's import Response. Next is the validation.
And it's import response. Next is the validation. So let's go ahead and do that. This validate. This is what we have to do. And make sure we have the error directives in our view. So let's go to that actually. So add comment. And there's only one here, and it should go underneath the textArea. And let's grab the error directive from our CreateIdea component.
And there's only one here, and it should go underneath the text area. And let's grab the error directive from our CreateIdea component. And just grab this one here. Okay. Just paste that in. Should be named error. I mean, not error, comment. And let's try that out actually. So let's say addComment for our form submission. Sorry, not that.
So let's say addComment for our form submission. Sorry, not that. Should be wire:submit.prevent="addComment". Okay. So let's try that out. Reply. Don't put anything in here. And it doesn't show the error message. Okay. So it's not submitting because I have two buttons here, and it doesn't know which one.
Persist comment to database7:17
So you can leave that in if you want, but I'm just going to rely on browser validation. So let's just add the required field here. Okay. And now the browser should handle that, but we still have server side validation. Okay. Now we can actually add the Comment. So let's do that back here. After we validate, let's go ahead and create that Comment. So Comment::create(). And we have a userId.
So Comment create. And we have a userId. And that should be the User who's logged in. And we should be logged in at this point. So auth()->id(). The idea is being passed in. So say this ideaId. And the comment or the body is this comment. Okay. Let's make sure to import Comment.
Okay. Let's make sure to import Comment. Let's go ahead and emit an event. Actually, we'll do that after I verify that it works. So let's also reset the text area so we can do this reset. And let's just say let's reset the comment. So it clears out the comment after it's submitted. So this comment. So let's go ahead and try that out. So it's not going to update this comments container yet because it's not within the
So let's go ahead and try that out. So it's not going to update this comments container yet because it's not within the same component. They are sibling components and we have to send events to each other. So let's just verify that it works and gets added to the database first. So let's refresh. Adding a comment. Okay. Okay. So it did make the request.
Emit events and refresh UI9:07
Okay. So it did make the request. Let's go ahead and check our database. So we have 495. If I refresh, we have 496. So if I just sort by the latest Comment here, it should be up here and there it is. So let's go ahead and emit that event. So we can do two things here, close the model and show the success message. So just like in our other components, let's take a look at one of them actually. And let's just grab this.
So just like in our other components, let's take a look at one of them actually. And let's just grab this. Let's go ahead and emit a new event. Let's name it commentWasAdded and let's say commentWasPosted for the success message. Okay. So let's go ahead and go to our addComment here. Let's go back up here and we want to listen for that event and close the modal. So it should be the same as our model component. So let's check that. So yeah, we need this keyDown listener on that event.
So let's check that. So yeah, we need this key down listener on that event. So let's steal this. Let's paste it in here. Sorry. Not that one should be this x in it. Okay. Paste that in. And the event is commentWasAdded. Okay.
And the event is Comment was added. Okay. And we just want to close the model or sorry, not the model, but this thing here. And we also want to show the success message in the bottom, right? So let me hide this for now. And we want to see that message here. So that should be in our notification, notification success. And we just have to add that new event here. Okay. Live our own Comment was added and that should be good.
Okay. Live our own Comment was added and that should be good. Okay. So let's see if that works. Actually one more thing here. We have to listen for the event on this component and refresh the comments. So let me just grab this comment was added. Let's go to our Idea comments. Let's listen for that event. So protected listeners equals comment was added.
Let's listen for that event. So protected $listeners equals commentWasAdded. And just like before, let's add a new method for commentWasAdded. And let's refresh the comments or in this case, the entire Idea, which will refresh the comments as well. So this Idea refresh. Okay. So now we did three things here and let's make sure that it works. So we have that new comment down here. Let's add a newer comment, newer comment.
So we have that new Comment down here. Let's add a newer Comment, newer Comment. Okay. So the model, sorry, not the model, the dialogue should hide. The message should come up and this container should show that new Comment. Okay. Comment was posted. It closed the dialogue and there is the new Comment. So everything is working. So one more thing I want to add here is a badge to show if this person is the person.
Add OP badge and optimize12:26
So everything is working. So one more thing I want to add here is a badge to show if this person is the person who created this Idea. So you can see the same thing in the Laracasts form. So this person, the guy is the OP and for any Comment that he makes here or he or she makes here, then it will show that badge. So let's do that quickly. So that's going to go in our Idea Comment and I'm not sure where it should go. Let's try before the username. So let's duplicate this and let's add something new in here.
Okay. So I think I like it this way better. Okay. So now let's do a check to make sure this person is the OP. So let's add a conditional here and let's put this in there. Actually this bullet should go in there too. Okay. And let's make sure it still renders. Okay. But if it is, it should render that new badge.
Okay. But if it is, it should render that new badge. Okay. So we have the comment here, so we can say comment user_id. So if this person who created the comment is the same as the person who created the idea. So how do we get that? So at this point we only have access to the comment. So we can say comment, you can grab the idea, we can grab the user and we can grab the id. So before we do that, let's take a look at debugbar here.
So we can say Comment, you can grab the Idea, we can grab the User and we can grab the ID. So before we do that, let's take a look at debug bar here. And you see we have 17 queries and 24 models. So now if I refresh, we have 31 and 38 now. So that's because for every Comment, we now have to make a query to check if this Comment's User is the same as the person who created the Comment or the Idea, I mean. So again, we do have an N plus one issue here. So the problem is right here when we're doing Comment Idea and we already do have the Idea up here. We just can't access it from the Comment component.
up here. We just can't access it from the Comment component. So what we can do is when we're looping over the comments in our parent component here, so idea.comments. So at this point, we have access to the idea, sorry, not this one. So let's look for the foreach here. And from here, we do have access to the idea, like I said. So if we pass that idea in, that idea has the userId of the User who created that idea. So we wouldn't have to make those extra queries. So let's go ahead and do that instead.
So we wouldn't have to make those extra queries. So let's go ahead and do that instead. So again, in our IdeaComment, we do have access to this Idea here, but we only need the user_id. So let's pass that in. So here, let's go ahead and pass that in and say ideaUserId is ideaUserId. Okay, let's go ahead and accept that IdeaComment right here. So let's say public ideaUserId. And it's added here, ideaUserId. And let's assign it here.
And it's added here, ideaUserId. And let's assign it here. This ideaUserId, okay. And now it should be available in that component. So back here, instead of doing this, we can just use this here. So comment, ideaUserId, like this. So let's try that out. Again, keep an eye on the queries and the models. So we have 31 and 38, it should go back down again. And we're back down to 17 and 24.
So we have 31 and 38, it should go back down again. And we're back down to 17 and 24. And now the OP badge should work. So there is no OP here, because this person did not comment here. But let's go ahead and go to my ideas. Let's go to this one. And there's no comment here. But if I do add one, it should work. Adding a comment, postComment. And it didn't show, did I do that correctly?
Adding a comment, post comment. And it didn't show, did I do that correctly? Sorry, it's not on the comment object, it's on the actual component itself. So we can just do it like this. And hopefully this should work now. And there it is. Cool. So if you want, you can extract this to a method, either on the User or the Comment. So say comment, say isAuthor, and pass in the idea user ID like this. But in this case, since I'm just using it in one place, I'm okay with just doing it.
So say Comment, say is author, and pass in the Idea userId like this. But in this case, since I'm just using it in one place, I'm okay with just doing it like this. So we'll end this video here. But in the next video, we'll add some nice UX additions. For example, after we add a Comment, I wanted to scroll to that Comment, and maybe highlight it a certain color for a certain amount of time. So I forgot to update this comments counter here. So if I add a Comment, you'll see that it doesn't update. So let's fix that.
So if I add a Comment, you'll see that it doesn't update. So let's fix that. Doesn't update. Okay, you see that this does not update. So let's fix that. Like I said, this is the same thing as our Idea Comments, we just have to add this listener and then add or refresh the Idea. So we should already have a bunch of listeners on the IdeaShow component. And we do. Let's just add that new one.
And we do. Let's just add that new one. Let me just put these on their own line. Okay, let's add that new one. So Comment was added. And let's add that method. So let me just put it down here. And now it should update the comment counter. So I have eight, if I add this new one, should be nine. And it does get updated.
So I have eight, if I add this new one, should be nine. And it does get updated. And it's still here. Awesome. So as always, let's make a commit. This is 49, git add, git commit, episode 49, add comments.
