Real-Time Chat with Laravel, Vue.js & Pusher

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] in this video tutorial we're going to be creating a real-time chat application with laravel vue.js and pusher to get started let's go ahead and jump over into our terminal before we start i want to make sure the necessary programs are installed so first let's do composer dash v now that we know composers installed and we have version 2.0.6 let's make sure that npm is installed we'll do npm-v and we can see we have 6.14.9 the last thing i want to check is for php-v and we have php version 7.4.3 as long as you have these three things installed you should be good to continue let's go ahead and clear this out to create our new composer project we'll use composer create dash project dash dash prefer dist and then laravel slash laravel and then the name of our project for this i'm just going to use chat app now that my new laravel project's been created let me clear this and let's cd into our chat app project now let's jump over and check out our project in vs code i'm going to navigate to my project it should be in my home directory in a folder called chat app and we're going to open up the entire folder so i'm in my env file that should be in the root and here we are we're dot env now that our composer project's created let's go ahead and connect it to a database i've already set up a database before i started this so if you haven't created the database yet go ahead and do that now and then we're going to change our database connection our username and our password so that our application can connect to the database for mine i just called my database chat app my username is going to be scriptster and my password is just password if you're doing this in production make sure to choose something a little more secure go ahead and save that and let's jump back over into the terminal the next thing i want to do is install larabelle sanctum to do that we're going to use composer again so composer require larabelle sanctum now that laravel sanctum's been added to our project let's clear this out and let's publish the laravel sanctum configuration and migration files to do that we'll use php artisan vendor publish dash dash provide equals and then inside of double quotes we're going to do laravel slash sanctum slash sanctum service provider so you can see we just created some new database migrations and a new config sanctum file let's check that out in vs code inside of our config we should have a new file called sanctum and that's this right here let's jump back over to the terminal i'm going to go ahead and clear this out now that sanctum's all set up and configured we're going to use jet stream inertia to get our project scaffolding up what that's going to do is it's basically going to set up our user login and authentication system as well as some of our blade templates and view templates to do that we'll use composer require laravel jetstream now that we've included it into our project i'm going to clear this and let's install it so we'll use php partisan jet stream install and then inertia now that we've successfully installed jet stream inertia into our project i'm going to clear this out i want to run php artisan migrate since we just created some new migration files now that we've run our migrations let's clear that and i want to run npm install to install our package.json dependencies now that all our dependencies have been added let's clear this out and i want to create the jet stream views so to do that we'll use php artisan vendor publish dash dash tag equals jet stream dash views now that we've created all of our views i want to clear this out i'm going to run php artisan serve to spin up a web server environment for my application to run on so let's go ahead and press enter now you can see starting laravel development server i'm going to go ahead and copy this url the next thing i want to do is i'm going to open up a new tab and this time i want to do npm run hot now what that's going to do is it's going to watch my project folder for changes anytime a change happens it's going to recompile my app.js file and then it's going to automatically refresh my google chrome browser so go ahead and press enter now we should be good to go let's open up our chrome browser i'm just going to paste in that website now here we go we have our default laravel installation which gives you all of this right here but then if you'll notice we also have login and register up here that's what jet stream inertia did for us it created a login page which is right here and this is the jet stream logo and then if we go back we also have this register page where we can create a new user we didn't have to write any of this code we didn't have to create these view files it's all created for us so let's go ahead and register a new user i'm going to click on name and for this i'm just going to use scriptster for email i'm just going to use scriptster scriptster.com and then for my password i'll just use password and then go ahead and click register if you want you can save this password i'm not going to so i'm just going to click on the x now this was all created for us using laravel jetstream which is what you see right here it automatically gave us this little drop down over here we click on profile we can see it automatically created this profile information view we have our update password if we want to we have our two factor authentication we also have browser sessions and then delete account this is a really quick way to get up and running without having to jump through a lot of hoops by default in laravel 8 they automatically include tailwind css so that's why we see this nice fancy looking dashboard when we log in without having to write any css at all now that users are able to log in and create accounts let's jump back over to the terminal and get a few things set up i'm going to create a new tab since we're creating a chat app i'm going to go ahead and create the model for a chat room so we'll use php artisan make model and i'm just going to call my model chat room and i'm going to put a dash m to create a migration file i'm going to do the same thing again except for this time instead of chat room all my chat rooms are going to have chat messages so let's create another migration and model for chat message all right now that we've created our models and migrations let's jump back over to vs code and i want to edit these migration files so i'm going to go into database migrations and then these last two are the two that i just created so this is create chat rooms table and this is create chat messages table so let's do the chat rooms table first so for the chat room table i just want to create a column called name so to do that we'll just do table string name and then add a semicolon at the end now let's save that command s to save and then let's do our create chat messages so for this i'm going to add three new columns the first column i want to add will do table integer and then for the integer i'm going to call it chat room id and this is going to be the id of the chat room that these chat messages belong to go ahead and add the semicolon i'm going to do another integer so we'll do table integer and this time it's just going to be user underscore id and this is going to be the id of the user who is creating this message go put the semicolon at the end and the last one i'm going to do we'll say table medium text and we'll just call this the message and that'll contain the message that our users send back and forth go ahead and save that command s and that should be it for our migration files let's go ahead and jump back over to the terminal let's clear this out and let's do php artisan migrate great so we just ran our migration files we'll clear this out again now by default i want to have a few chat rooms created for my application so i'm going to create a seeder file to do that we'll do php artisan make cedar and we're going to call it chatroom seeder and then just press enter let's go ahead and add some information to that cder file we'll jump back over to vs code we can close these out and instead of migrations i'm going to go to cders and you can see we have a new file here called chatroom seeder let's open that up so what this file is going to do for us we're going to be able to seed some data we're just going to create some default chat rooms for our application right off the bat so inside our seeder file we want to bring in the facades db so we can say use illuminate slash support slash facades slash db and then a semicolon now we can use that down here so we should be able to say db colon colon table and the name of the table for this cder is going to be chat underscore rooms because we want to create some default chat rooms and then we should be able to say insert and then pass it in array now the only column in our chat rooms table that we want to update is called name so let's do name and then we want to give it a default name i'm just going to use general and then close it off right here now we should be able to just duplicate this down and i want to create a second default chat room and we'll just call it tech talk and then command s to save now that we've created our seeder file with some information that we'd like to populate into our chat rooms table let's go ahead and tell our database seeder file to run that we can get rid of all this and we can say this call will pass it in array and we're just going to tell it to use the chat room seeder so we can say chat room cedar colon colon class and then let's close it off right here with a semicolon command s to save and we should be good for our database seeders now let's jump back over to our terminal and tell it to run this seeder for us for that there's a php artist in command we should be able to say php artisan db seed and we just seated our database with that information let's go ahead and clear this out and jump back over to vs code i want to create some model relationships so let's close these out we should be able to minimize this and let's open our app and then models and let's create some relationships for our chat room first so right after use has factory i'm going to create a new public function and we're just going to call it messages so every chat room is going to have a relationship called messages and that relationship is going to return we can say this and we'll use has many and then we have to pass it the model that it has many of so we should be able to say app slash models chat message so our chat room uses a has many relationship for chat message and then let's go ahead and close that off and then command s to save now let's do the same thing and create a few relationships for our chat message right after our user factory we'll do public function and our chat message is going to have a room relationship inside of that we'll do return and then this each chat message can only have one so we'll say has one and then we'll pass it the name of the model that it has one of and for this it will be app slash models slash chat room and then we need to say how these are connected for this we can do id and then chat room id now that we've said our chat message can have one chat room our chat message can also only have one user so i'm going to duplicate this and we'll change this to user and then instead of app models chat room we'll say app models user for the user model and then instead of chat room id we can say user underscore id go ahead and command s to save that and we should be good on our model relationships so let's close out of this and we'll jump back over to our terminal now that we've seeded some data into our application and we've created some models with relationships let's go ahead and create a controller that can communicate with those database tables and models for this i'm going to use php artisan make controller and then the name of the controller we want to create for this i'm just going to use chat controller and then press enter i'll clear this out and let's jump back over to vs code now if we minimize this and we go into http controllers we should see a new chat controller the first thing i want to do is import my models we'll say use app slash models slash chat room and then we'll duplicate that down and for the second one we'll do chat message and that should bring in our chat room model and our chat message model and the next thing i want to bring in is use illuminate slash support slash facades slash auth now let's go ahead and jump down into our class and create some functions the first function i'm going to create is going to be the rooms function because i just want to return all the rooms in our chat room table so let's do public function rooms we'll pass it the request and for our public function rooms let's just do return chat room colon colon all and that should be it we just want to return all the rooms if we really wanted to get crazy we could paginate all the returns but then this video would end up being much much longer so for right now i'm just going to return all after our public function rooms let's create another function and for this we'll just do messages because we want to return the messages so we'll say public function messages and again we want to provide the request to our function and then in addition to the request i want to pass in the room id so when i create my route i'm expecting to receive an id at the end of it and for that i'm just going to use room id now i can use the request received and the room id received in the route so let's go ahead and return chat message colon colon where and then we'll use chat underscore room underscore id and we want that chat room id to match the room id of the route after that we want to return it with and we'll use the user because we created that user relationship and then we want to order by and we'll say we have a created underscore at column in our chat message table so we want to order by the created at and we'll say desc for descending i just paused the video i don't realize this until later on but i actually typed created wrong i said it correctly out loud but i only typed the word create this should be created i'm going to leave it in here for now so you can see how i debug this later on but if you want to avoid this mistake make sure you type created with a d at the end and then let's just say get let's go ahead and create one more function and for this this is going to be the creation of a new message so we'll say public function new message we'll pass it in the request and we'll also pass the room id again so this is the id of the room that we want this new message to be posted to now inside here i'm going to use new message as a variable and i'm going to set the equal to a new chat message now that i have the new chat message model we should be able to say new message and then for the user underscore id i want to set the equal to the auth colon colon id and we pulled that in earlier up here when we said use illuminate support facades auth so we're going to set this new message user id to whoever the authenticated user is that's currently sending us the message after that let's do new message and then we're going to set a chat room id for this incoming message and for that i'm just going to set it equal to the room id of the incoming route that we pass in right here and then close that off with a semicolon and then the last thing we want to do is the message so we'll say new message message and we'll set that equal to the request message now that we've set all the parameters let's go ahead and save that so we'll do new message save and then let's just return the new message and that should be it for our controller so command s to save now let's jump over to our routes and create some endpoints to hit these controller functions i'm going to go ahead and minimize these and we're going to go down to our routes and then web so in order to create some routes that go to our chat controller first thing we need to do is bring it in so we can use it so we'll do use app slash http slash controllers slash chat controller now that we've brought in our chat controller let's go down here and add a few routes the first route is going to be our chat rooms we just want to grab all of our chat rooms in order to do that we'll use route colon colon middleware and then we want to use our auth colon sanctum and then we need to provide our method for this we're going to use a get method the first parameter this takes is our route so we're going to use slash chat slash rooms because we want our url to be the root domain slash chat rooms and it wants to grab all rooms the second parameter is going to be an array and we need to pass it the chat controller colon colon class and then we'll put a comma and the second part of this array is going to be the function within this controller that we want this route to access for this it's just going to be rooms for the room's function i'm going to go ahead and duplicate this line and we're going to do another get method this second route is going to be our messages route so instead of rooms plural we want room singular and then we want the room id so we'll say room id inside of these curly braces and then a slash and then messages we want this route to hit the chat controller but instead of rooms we want it to hit the messages function so now we should have our root domain slash chat slash room and id which would be a number one or a number two or three and then slash messages let's go ahead and create one more route i'm just duplicating that row and this time instead of get we're going to use post now we want to post new messages so we're going to use slash chat slash room we want the room id that we're posting it to and then for this route we'll use message so slash chat slash room slash the room id will say room 1 and then the word message because we're passing in a new message we're going to use chat controller inside of our array but this time instead of messages we want it to hit the new message function and that should be good command s to save now the only other thing i want to do in here is create another visual route right here you'll see we have this route to the dashboard i want a new view for the chat so i'm going to copy this and we're just going to duplicate this entire thing this time instead of dashboard i want the chat view to be at the root domain slash chat i want to render instead of dashboard we're going to be creating a folder called chat slash and then a file called container.view so we're telling it to render the chat slash container and we haven't created that yet but we're going to in a minute the other thing we want to do is instead of name dashboard we want to rename this to name chat and that should be good so go ahead and command s to save at this point i just want to jump back over to my application and make sure i haven't broken anything i'm just coming back over here and i'm just going to refresh the page everything appears to be working so we should be good to go now that i've created that slash chat route right now we're at slash dashboard but we just created a new route called slash chat i want to create a link right here that says chat so let's go ahead and create those view files now that we have a route pointing at it let's jump back over to vs code we should be good with these so i'm going to close this out i'm going to close out my chat controller we can minimize this and we can minimize app and we can minimize our routes now let's jump over into resources js and then inside of pages i'm going to create a new folder and i'm just going to call it chat and inside of that folder i'm going to create a new file called container.view now let's go ahead and give that the default scaffolding so we'll do template and then let's also pass in some script tags i'm going to go ahead and put some div tags in here that just says container so i know this is the container command s to save that and i'm going to create some additional view files i want to create a toggle or a way for users to switch between so a chat room selection so i'm going to create a new file and we'll call this chat room selection dot view and i'm going to copy the code from my container and i'm just going to paste it in here and we'll just say selection view and we'll command s to save that so now we have our container component we have our chat room selection i also want to create another view file for my messages container somewhere for all my messages to live let's call that message container dot view and we'll just paste in the same thing again and we'll just say message container command has to save that i'm also going to have inside of my message container i'm going to loop through all the messages in my chat room so i want to create another component that just contains the message itself and then we'll loop through that component and provide it some information so let's create another component and we'll call this one message item dot view we'll paste in that same code and i'm just going to say message item and command s to save that the last thing i want to create is an input we have to have somewhere to input our new message so i want to create a component that holds the input for our chat so we'll come back over here we'll say new file and this one we'll just call input message dot view we'll paste the same code in again and we're just going to say input message so now we have five new components we just put some default scaffolding in here and we created our route and that route points at this container.view file but we haven't given our application a link to actually hit that file let's jump back over to our google chrome browser and see if we manually go to that route if we put right here and we just say chat we get our container cool but we want it to match the rest of the website so let's go back and open up vs code and since i want the container to match the entire look and layout of the dashboard i'm just going to go ahead and copy all of this we're going to go back up to our container.view and we're going to paste it all in now instead of welcome i'm going to go ahead and get rid of this and instead of our welcome we're just going to say container because this is our container view i can get rid of this component right here and i'm going to remove this where it says dashboard and we're just going to say chat because this is the heading at the top of the page so command s to save that let's go back over to our google chrome browser let's go back to our chat and we can see it looks the same as our dashboard except it says chat and then we have our container so we're hitting our container and our chat route works let's go ahead and add a link right here so we can hit this route from anywhere in our application we'll jump back over to vs code now in order to change that link at the top we can see we're using the app layout component so let's go up here to our layouts we can see it's in layouts and then app layout so let's open that up layouts app layout and i want to create an additional link so right now we can see we have this link right here and then we have our route dashboard let's just duplicate that so instead of dashboard we're just going to say chat because we want the chat route and instead of current dashboard we'll change it to current chat and then we'll change this right here to say chat as well now there's one other place in this code that contains a link if we scroll down to the bottom we should see right here and this is our responsive navigation menu we want this to also contain the link to our chat so we'll duplicate that we're going to do the same thing as above we'll change the route to chat we'll change current to chat and we're going to change this right here to chat command s to save and if you see right here my laravel mix build was successful let's jump back over to the chrome browser and now i have a new link up here for chat i can navigate to dashboard i can navigate to chat and i'm hitting that file in chat slash container so now that my routing is all set up and we can hit this container let's go ahead and create some of these view components let's jump back over to vs code and i'm going to close all these out since we don't need them open right now let's go ahead and add some of these components that we just created into our container view i'm pretty sure my ide should be smart enough if i do message container it automatically imported it right here and then let's just do message container and then let's also right underneath of that let's do input dash message we'll close that off it imported my input message and i just want to clean this up a little bit and that should be good and will command us to save now if we go back over to our chrome browser we see our message container and our input message let's go back over to vs code and build out these views before we can go ahead and build the views there's a few things we need to do first when this page is loaded we want to go ahead and we want to grab all of the rooms that are available to our chat application so let's go down here and create a new method right after components we'll do methods and let's just create a new method called get rooms and this is just going to get all the rooms available in that rooms table that we created earlier we're going to use axios for this so let's do axios.get and our route should be slash chat slash rooms then we want to do something with the response so we'll use our arrow functions when we get our response we want to save the chat rooms so let's go back up here and before we do anything let's create some data properties so we're going to pass in a function and then we're going to return our properties so for the first property we'll just do chat rooms because we need somewhere to store the rooms when we hit this api endpoint we plan on receiving these rooms as an array so we'll just say that it's an array put a comma here so it doesn't yell at us anymore i'm going to command s to save that we're probably also going to want to set a current room so let's just do current room by default we'll just pass it an empty array and then we haven't done this yet but we're also going to want to grab the messages for the current room so i'm just going to create another data property and call it messages and that's also just going to be an empty array and we'll put a comma right there and command s to save so now that we have these data properties let's do this get rooms and let's set the response to this dot chat rooms and we'll set it equal to response dot data so now when we receive this response it's going to take the response data which is hopefully all of our chat rooms and save it in this data property of chat rooms right here the next thing we want to do is we want to set a default room when our chat page opens there's no default so it's just going to grab all the rooms by default i'm just going to set that to whatever the first room is in the response that we receive but i want to do that in a separate method so let's go down here and we'll do set room and we're going to receive a room and we want to set the current room so that should be this dot current room and we want to set it to the room that we receive so now that we have this method down here let's go ahead and we should be able to say this dot set room and we want to set it to the response dot data and then the first value it receives so we'll just set the data array to zero and that should set the current room and then let's just catch our error we'll do catch error with an arrow function and we'll just console.log the error and command s to save now that we have this method of get rooms we haven't told our application to fire this method yet so let's use the created and tell it to this dot get rooms so now whenever our application loads for the first time when it creates this container view we're telling it to this dot get rooms it's going to go up here to our get rooms it's going to fire off our axios get method and it's going to save all of the chat rooms available to us and it's going to set a current room for us so let's command s to save that since we're receiving our current room we want to let our input up here so when a user does some input we want to let this input know which room it's for so let's go ahead and we'll do room and this is going to be a prop on the input message component so let's say room equals current room so we're passing it all of the data that's inside of this current room when we set the current room so let's command us to save that and let's just add that prop into our input message so right down here after export default we'll say props and we'll just say room so now we know that we're receiving this prop of the room we'll command s to save that the next thing we want to do is when we change a room or when we receive our current room we want to get all the messages for that room so let's add another method down here we'll do it right after set room and we'll just do get messages we're going to use axios again and it's going to be a get request and this time we're going to hit a different route so we'll do slash chat slash room and then we'll do plus this dot current room dot id because we want the id of the current room we said we were going to pass a room id when we hit this route so we'll do this dot current room dot id plus and then we can do slash messages then with the response we'll do response and we'll use an arrow function and since we created this messages data property up here let's set the response to this dot messages equals response dot data so set the messages to the response data that we receive and then let's also do a catch down here and we'll do error arrow function and we'll console.log error command s to save so now we can get rooms we can set our current room and we can get messages for our current room but we haven't actually fired off our get messages yet so when we set our current room let's also say get messages so we'll do this dot get messages so whenever the current room is set get the messages for that current room now let's jump back over to google chrome and make sure we don't have any errors so let's pull up our developer tools and we're getting a 500 internal server error let's go over to our network i'm going to refresh this and on our messages column not found unknown column create at so this is actually incorrect this should be created with a d right here at let's jump back over to vs code and we'll go up to our app http controllers chat controller and right here we want created at i typed that wrong previously i probably should have checked this but i didn't command s to save that and let's jump back over to chrome and we'll refresh this page and hopefully messages we get an empty array because there's no messages yet our rooms we're receiving all of our rooms so that's good and let's click on view we'll do inertia and we'll expand that and we have our container we have our current room so we set our current room we received our chat rooms array and we can see that right here so everything looks like it's good to go i'm going to close this out right now now that we're able to receive our rooms let's go ahead and create the input message so that we can add new messages for that room jump back over to vs code i can close this out back in our container let's scroll back up and we are passing the input message the current room so our input message is receiving a prop of room let's go ahead and create this component so that we're able to add new messages for whatever the current room we're in so i'm going to go ahead and get rid of this because this was just to help me get things set up so this time we'll do div we'll set a class we're using tailwinds for this and i already went ahead and wrote down some loose class stylization so i'm just going to roll with that we'll do relative h.10 and m-1 we'll close that off and let's close off our div now i want to add a border to the top of my input message because i want to create a little separation between the input box and the messages above and i did that with raw css feel free to go back and change this up to make it look however you want but i'm going to use style and i'm going to set that equal to border top and we'll say 1px solid and i'm using e6 e6 e6 which is a light gray after that i'm going to set a class and we'll set that equal to grid and then grid dash calls dash 6. and then let's close that off as well and let's put our input inside of here input and i'm going to do type text we actually need to create a data property to attach this with a v model i'm going to type it in right now and then we'll add it below so we'll do v dash model and we're going to set that equal to message we're also going to create a method below i want the user when they press the enter key i want them to be able to press enter to send the message instead of having to click a button we're going to add a button too but i want the enter key to send a message so we'll do at key up dot enter and then whatever the method name is so we didn't create it yet but we're going to call it send message we're also going to do a placeholder of say something dot dot dot let's also give this a class and we'll use call dash span dash five we'll do outline dash none that removes the focus border and a p-1 for padding and then let's close this off and our text editor is done yelling at us so we also want to add a button in here so we'll do button and we're going to do at click or our button and when the user clicks the button we want to do the same thing so send message we're also going to add some class styling so we'll do class equals and we'll do place dash self dash end we're going to do bg dash gray dash 500 and then we're going to add a hover color so when they hover over the button it changes color in tailwinds we can do that with hover colon bg dash blue dash 700 and then we'll add a p 1 for some padding we'll add an empty dash 1 for margin top we're going to change it to rounded so the button has some rounded corners and let's do text dash white we'll close that off our button is just going to say send and then let's close that off at the end i'm going to clean this up a little bit we'll just push that over and i'm going to pull this back so there we go we have our input and we have our button i'm going to command s to save and let's create this v model message property down here so right after props we'll do data and function and that's going to return our data properties so our only data property in here right now is message and i'm just going to set it blank by default we also need to create our send message method so right after data let's go ahead and add some methods and we said we're going to call this send message if you want to do some more form validation feel free i'm trying to keep this quick and simple so i'm just going to say if this dot message is equal to nothing we'll just do return so if they didn't put anything in the message box don't allow him to press the send button after that we're going to use axios with a post request so we'll say axios dot post we want to hit slash chat slash room slash and then the room id which we're passing in with this props room so we should be able to say plus this dot room dot id plus slash message after that we want to pass it some data so we're going to say message colon and then this dot message to pass it this message right here that we're using v bind to bind our input with so we're gonna send whatever's in the input after that we wanna check and make sure our response was successful so let's do dot then and we'll do response with an arrow function and i'm just going to say if response dot status double equals 201 so if it was a successful creation let's reset the message back to nothing so we'll do this dot message equals and then nothing after we reset the message back to nothing we probably want to emit an event back to our parent component to say hey this message was sent successfully if you need to do anything when messages were sent successfully go ahead and do that so i'm going to use this and then dollar sign emit and i'm just going to say message sent because we sent a message and it was successful we want to let our parent component know that that happened after that let's do dot catch let me just scroll down a little and we'll do error we'll use an arrow function and we'll do console.log error and then command s to save let's jump back over to google chrome and see if we're able to send a message successfully so let's go ahead and type something in here we'll just do this is a test when we hover over we're getting our blue but we should be able to just press enter and we can see our text went away let's check our chrome developer tools and we'll go to network i'm going to refresh this again and we'll just say another test and we want to check for a network event down here so we'll press enter and we can see we hit message it went to our chat slash room slash the room id of one and we posted this new message let's check our response and we received the new message response that we set earlier in our controller so this is good we're able to send messages for the current room that we're in i'm going to close this out now let's make sure that we can display messages in here in our message container so let's jump back over to vs code i want to go ahead and create this emit event on our parent component which is the container.view we're calling it message sent so i'm just going to copy that let's go back over to our container and right here in our input message after our current room let's use the dash on and we'll use our message sent and whenever a message is sent we want to fire off the get messages method and since we already created that method down here right here this should fire automatically for us so let's command s to save i'm going to go back to we'll jump back over to chrome let's open up our developer tools and we'll go to our network tab and we'll just type hello this time we're expecting two network events so let's go ahead and press enter and we have our two network events we have our message which is our post if we come over here to our headers this is our post and then we have our is this is our get request when we're asking for all the messages for this chat room in particular so let's close that out now that we're able to send messages and we're able to pull them from our back end let's go ahead and display some messages right here in our message container let's jump back over to vs code and this time we're setting all of the messages right here when we get messages we're setting them all right here in our data property so let's pass that as a prop to our message container we'll do messages and we'll pass that as messages command s to save now our message container is receiving all of these messages let's go ahead and build this message container view so over here on our message container we should be able to get rid of this and i've already wrote down some general tailwind css for this so we're just going to do div class we'll set that equal to h dash 96 and w dash full which will make this expand the full width of the container so let's close that out and let's also do div class and we're going to set that to h dash full for the height full height we'll do a p 2 and then flex we'll do flex dash call dash reverse because we want this to be at the bottom of our div and then we'll also do overflow dash scroll and now we want all of our messages to show up inside of here so this flex reverse is going to reverse the order of our messages to show up with the newest message at the bottom so now that our message container is set up we want to loop through all of our messages before we can do that we need to receive the messages from our parent as a prop so let's set that prop and we said we're going to pass it in as messages so now that we have this prop of messages and we pass that in right here using this we should be able to use it in our message container in order to do that we're going to use a div and then a v 4 because we want to loop through all these messages inside of our v4 we're going to do message comma index because we want to create an index for all of these and then in messages now we can set a key set to our index so now we're looping through all of our messages and each time it loops through it creates this variable for us called message and we can access all the properties inside of each individual message we're also creating an index for each one and then we're setting our key for each item to index now that we've looped through we want to use that message item that we created earlier inside of our message container so let's go ahead and we'll say message item and you can see my ide automatically said import message item from messageitem.view and it set this components right here to an object of message item so let's go ahead and pass the message properties to our message item so let's say message equals message so now our message item is receiving the individual message each time we loop through let's save that and let's finish creating this message item view and this should be super simple first thing i want to do is i want to add the prop so we'll say props and we're receiving it and we called it message so now we have access to this property of message inside of our div i'm going to delete the message item in here we'll just use the mustache tags here and we'll say message.user.name i'm just going to do a colon and then the mustache tags again and we'll say message dot message and then let's save that now if we jump back over to google chrome we should see some new messages and there we go we've reversed our list so our newest message is showing up at the bottom let's try this again hi there so when we said hi there it told our parent component container.view hey a message was sent go grab all the messages again when it grabbed all the messages again it passed all the messages to our message container dot view and then that message container dot view looped through all messages again now that this is all working let's go ahead and finish that chat room selection view so that we can toggle between different chat rooms so let's open up vs code again and we're going to go back into our container and i want to put the chat room selection at the top so right now we just have a heading or a title that says chat let's change that so that it uses our chat room selection so we'll do chat room selection it automatically imported it down for me i'm gonna tab that over and it automatically brought it down here so we've imported it for the chat room selection let's close that off first thing i want to do is i don't want to provide a selection if there's no rooms to select from so i'm going to use a v dash if i'm going to set it equal to current room dot id so if there's a current room and there's an id allow this to be shown so that's assuming there's at least one room and it's set to current after we check if there's a current room id we want to pass all the rooms as a prop to our chat room selection component so let's do rooms and set that equal to chat rooms since we're storing that right here so we can pass the chat rooms and we're passing it as a prop called rooms let's also pass the current room and we'll set that equal to current room the next thing i want to do is i want to watch for an event this chat room selection is actually going to be a drop down menu that we're going to create so i want to know when a user chooses another option in the drop down menu so i'm going to use v-1 and we're going to set that to room changed so we're going to listen for a room changed event and we'll set that equal to set room and we want to pass it the room that we want to set it to and for this we're just going to say event we're going to pass the room as the event since we've already created this set room down here we should be good to go we just have to pass it the room that it needs now that this is created i'm going to command s to save that and let's jump over to our chat room selection view so the first thing i want to do is i want to bring in the props so we said we're going to have rooms as well as current room we're going to receive both of those as props the next thing i want to do is i want to provide some data i want to do we'll do function and return and i want to return selected as a data property because when we create this drop down list i want to know what is selected so we're going to use v model to bind that to this selected data property now that we have some data let's go ahead and do created when this component is created i want to set this dot selected and i want to set it to the current room so whatever we pass as a prop to the current room i want to set that to the selection on the drop down box so we should be able to say this dot current room and that should be good so we'll save that and let's redo this up here now i already have a general idea for some tailwinds css that i'm going to use for this so for the first div we're going to say class equals and we'll do grid and then grid dash calls dash 2. we'll close that off and we'll close off our div and for the next one i want to keep the name of the chat room that's selected to the left hand side of the screen previously it just said chat i want to say the name of the room and then the word chat so for that we're going to use div we'll use class and we'll do font dash bold text dash xl we'll close that off and then let's close off our div and then in here we'll use some mustache tags and we'll just say selected dot name so whatever selected is set to grab the name and display that over here and then after that put the word chat so if we have general chat selected it's going to say general and then the word chat after that we'll do another div and then let's go ahead and close this div off and then inside of that i want to do select on the next line we'll do v model and we'll set that equal to our selected data property we created we want to emit an event we want that event to happen at change so when this changes then fire the event so we can use so we can say dollar sign emit parentheses and then inside of those parentheses the first thing we want to say is the name of the event and we want to fire the room changed event and what do we want to do when that fires we want to pass selected so whatever the new selected room is we want to pass that back to our event watcher on our parent component so we'll say select it on the next line i'm just going to float this to the right so that this drop down box is on the right hand side of the screen the name of the chat is on the left hand side and i can close that off and then let's close off our select now inside of our select statement we're going to use option with v4 so we can loop through the list of options for our drop down box so we'll do option and then on the next line we'll say v-4 and we're going to set that equal to and we can say room comma index in rooms and then we need to provide a key so we'll say key equals and we'll set that to the index let's close this so it stops yelling at me so now we're going to loop through all the rooms each time we loop through we'll have access to this room object and each time we loop through it's going to give us a new index so each time it'll be key 1 the next time it'll be key 2 key 3 and so on we want to set the value so we'll say value equals and we'll just say room so the entire object of room and then down here let's close this off and for the option we need to provide some type of name or identifier so we know what option we're picking so we'll use the mustache tags and inside we'll say room dot name so let's save that and we should have our title and drop down box in our chrome browser so let's go take a look so now we have general and tech talk if i click this it should automatically change the text down here it'll actually probably go blank since there's nothing inside of tech talk yet but let's try cool it changed our tech talk title up here it changed this so it's no longer saying anything and now we're back in our general chat now that everything's connected we can do the last piece which is include pusher in our project which will handle the real-time notifications for us to get pusher set up let's go ahead over to pusher.com and create an account or at least get signed in so if you don't have an account already go ahead and click sign up and go through the process i'm going to use sign in and i'm just going to sign in with my github account i'm going to use channels for this so i'm just going to click get started for channel now that i'm inside of channels i'm going to create a new app for this i'm just going to call it chat app for my cluster us2 is fine and you could create multiple environments if you were going to have a development environment a staging environment a production environment you would use this we're just doing this as a demo in our local environment so it doesn't really matter for front end i'm going to select view for back end i'll select laravel and let's do create app they give us some demo code that we could copy and paste into our application but we're not going to use any of that so let's just click on app keys so this is what i'm really interested in i want to copy this app id and let's jump back over to vs code i should be able to close out most of this for right now we'll end up coming back to these later and we'll minimize this and what i really want to look at is our dot env file so at the bottom we have this pusher app id let's paste in that app id let's go back to chrome and we need our pusher app key our app secret let's copy our key we'll paste our key in we'll go back to chrome we'll copy our secret we'll paste our secret in and i believe our cluster was us2 but let's just double check that and it was us2 the other thing i want to do in here is we need to change the broadcast driver instead of log we want to change it to pusher and then that should be good so go ahead and save that enb file there's one other thing i want to point out if we jump back over to chrome and we go to our app settings now if you've used pusher before there's a new feature in here and this actually threw me through a loop when i was recording this video they have this enable authorized connections what this is is it says closes connections which fail to subscribe to a private presence channel within a timeout before enabling this ensure a client subscribes to at least one private or presence channel now this is a security feature sometimes in pusher if you weren't using private or presence channels anybody could kind of hop onto your channel because you're not checking for authentication somebody could find out what that link was and they could occupy a connection with pusher we're using a free account which i believe is up to 100 connections but if somebody was to find out that free account and the url that you're using they could occupy a connection and we don't want that so we're going to toggle this on so enable authorized connections now it's important to know that when you do that you're saying that you have to create a private or presence channel within a certain timeout so when we create this channel we want to make sure that it's a private channel or a presence channel and we have to check for authorization into that channel once you're inside of our application you can use any channel you want but we're making sure that you're an authorized connection before getting in there i'm going to leave the rest of these settings as the default you could come in if you wanted to allow client events or force tls it's up to you since this is just a demo i just wanted to give a general understanding of what this app settings is and why you should probably at least enable authorized connections and you can see our app was updated successfully now that this is all set up let's go back to our laravel app and we'll go back into vs code since we have our environment file set up we shouldn't have to look at this again i've already saved it so i'm going to close out of this the next thing i want to do is i want to go into our config and then app now i need to scroll down and find broadcast service provider so right here this by default is commented out we're going to be using this so go ahead and uncomment that command us to save and that should be good we can close this file the next thing i want to do is i want to open up the terminal again and we want to use composer to require pusher so let's do composer require pusher slash pusher dash php dash server and then we'll use a tilde 4.0 and close your quotations now that we've required it for composer let's clear this out now let's do npm install dash dash save laravel dash echo space pusher dash js all right i'm going to clear this out again now let's get pusher set up on our front end so let's open up vs code again this time we can minimize this and inside of our resources js we have this bootstrap file the bottom of this file we have this import echo pusher highlight all this and we'll remove the comments so we just want to make sure that all of this is uncommented and we really don't have to do anything else here so just command s to save what this does is it sets up pusher and laravel echo on our front end now if you're wondering what this process key env mix pusher app key if we go back into our env file that's this right here so we're actually passing our pusher app key this to our front end in this mix pusher app key variable so let's close that out this should be good to go we don't have to change anything else here so you can go ahead and close this the next thing i want to do is i want to open up our webpack.mix.js and i just want to require one additional thing in here i'm going to do require parentheses and then dot env and then outside we'll do dot config and then some ending parentheses and then save that this is so that it can process the dot env environment variables so that should be good to go we can close out of that now that we have pusher set up we want to create an event and a listener to do that we're going to go up to app providers and then inside of our event service provider we're going to add some additional event listener mappings so for that we'll do app slash events slash and we want to call this event new chat message so when a new chat message happens that's going to be an event and we want to listen for that i don't know if we're definitely going to use this listener but let's go ahead and create it and if this video doesn't get too long we'll try and squeeze it in so our listener is going to be we'll put that inside of an array the reason this is inside of an array is because you can have multiple things listening for this for instance if we had a new chat message and every time a new chat message happened we wanted multiple things to be triggered we could trigger an email we could trigger an in-app notification we could trigger text message notification but for this we're going to create a listener and we're going to call it app slash listeners slash send chat message notification and that should be good so command s to save and now we want to generate these files and we can do that with the php artisan command so let's jump back over into the terminal now we can do php artisan event colon generate and then press enter and now you can see events and listeners generated successfully so let's go ahead and check those out back in vs code we have now event new chat message.php so let's go ahead and modify this event first thing i want to do is i want to say use app slash models slash chat message because i want to bring that in now that i've done that let's go ahead right down here under use dispatchable we'll do public and then we'll create this new variable called chat message come down here into our construct and we can say chat message and set that to the variable chat message and then we'll do this chat message equals chat message the next thing i want to do is implements and then should broadcast so we'll copy that and we'll paste that right here now let's go down to our broadcast on by default it already has this return new private channel and then a channel name we're going to change that and we're going to call our channel chat period and then after the period we want to provide this chat message and then chat room id so we want our channel name to be chat period and then the number one or the number two or whatever the id is so command s to save that and we should be done with this file now that we've created this event let's go ahead and use it so i'm going to close out of this new chat message i can close out of this event service provider and let's open up our http controllers and then our chat controller now that we created an event let's use it in our chat controller so we'll do app slash events slash new chat message and since we brought it in i'm just going to copy this now down here on our new message right before our return we want to fire off this event so we're going to say broadcast and then new new chat message and then the message we want to broadcast is new message and since we're using this broadcast we can say to others what that's going to do is it's only going to send this event to other people it's not going to notify me about the event since i'm the one that triggered the event so go ahead and command us to save that and we should be done inside this chat controller now that we've created an event with a broadcast and a channel let's go ahead and add that to our route channels so down here under routes we have this channels.php now we want to bring in authentication so i'm going to go ahead and duplicate this and just say auth so we have illuminate support facades and then off now that we've brought in auth we can use it down here i'm going to duplicate this again too and for right here we're going to change the channel to chat since we know we want it to be chat period and then room id we want the id of the room and that's how we're naming the chat channel so chat period 1 chat period 2 and so on the other thing we're going to do is we're going to pass in the room id right here we could have left it as id i'm just being more specific we could have just said id id but at least now we know if somebody else looks at this we're passing in the room id the next thing we want to do is we want to get rid of this and we're going to do our authentication so let's do if auth colon colon check so if this user is authorized we're going to return an array and inside that array we'll do the id of the user so we can say user id and then the second parameter we want to return is the name and the user name so we'll say user name and then close that off we could use the room id above that we're passing in to check and see if the user has permission to access this specific room but we don't care what room they're accessing as long as they're authorized within our application and that should be good so we're doing our check if the user is authorized go ahead and return this array that contains an id for the user id and a name for the user name go ahead and save that and this file should be good now let's jump back over to our front end and we'll go in our resources js and then pages chat and we want to open up our container.view again now that we set up all our pusher connections and we created our pusher account we set up our env file we added our broadcast and our events let's go ahead and configure this file to use pusher websockets to do that i'm going to create a new method down here so right inside of methods i'm just going to create a new one called connect now inside of our connect method i'm going to say if this dot current room dot id so if there is a current room id set let's do something the first thing i'm going to do is i'll say let vm equal this the next thing i want to do is on connect i want to get messages so we're going to change this around a little bit so instead of set room get messages i'm going to get messages right inside of this connect method so we'll say this dot get messages then we'll do window dot echo dot private since this is going to be a private channel chat period and then plus this dot current room dot id because we know the name of the channel has to be chat period and then a room id then we can say dot listen and then we're gonna listen for an event called new message we didn't set that up yet i'm gonna go back into the event file and do that momentarily now what listen is it wants to listen for a specific event on this channel there can be multiple types of events but for this we want to listen for a new message so for that i'm going to do period message period new and then we'll just say e arrow function vm dot get messages now i want to watch for the current room and i want to say if it changes fire off this connect method so right after data we'll say watch and then we can say watch for the current room and if it changes we want to fire off the this dot connect so connect to whatever the new room is i'm going to command s to save this and let's jump back over to our chrome browser and see how this is looking so i want to bring up my chrome developer tools and i'm going to click on network tab i also still am logged into pusher so if we come back over here and we click on debug console we should see network events as they happen right here so i'm going to click on laravel again we're going to look for some network activity and then we want to check out the debug console so let's do command r to refresh and we can see we have this websocket right here we also have this other websocket initial subscription succeeded and pusher subscribe so it looks like we've connected and we've authorized over here and we have this websocket we go over to our debug console for pusher we can see that we have this connection authorized subscribed and now it's occupied and we're in private dash chat period one because we used an echo private channel it automatically put the private dash before the chat period 1. so let's go back over to laravel i'm going to go ahead and close the developer tools now that we know that we can authorize a user and subscribe to a specific chat channel or room we want to make sure we disconnect from a channel when we use our chat room selector up here so if i select tech talk i want to make sure i unsubscribe from general so let's go back over to vs code to disconnect i'm going to create a new method down here right after connect we'll add a new method we'll call it dis connect for a disconnect method i want to pass in the room we want to disconnect from and then in order to disconnect we'll do window window.echo dot leave and then we want to tell it what room we want to leave or disconnect from for this we'll use chat period and then we'll say plus room id and then close it off now that we have a disconnect method we want to come up here to our watch current room and we want to see if this user was previously subscribed to a room before changing to the new current room for that i'm going to pass in val which is the new value and then old val which is the old value and this will provide me the old value if the user was previously subscribed to a room prior to the current room changing so right before our this dot connect we want to do a check we'll say if old val dot id so if the old value or the old room has an id we want to run our method so this dot disconnect and then inside of this dot disconnect we want to pass it the old room or in this case the old val which is the old room command s to save that and let's jump back over into chrome and test this out let's go back into our debug console i want to go ahead and refresh this so that we have a clean slate and we'll go back into laravel now if i refresh the page and we look at our debug console we can see we've authorized subscribed and occupied now we want to see if we change this general to tech talk we see our tech talk chat changed we're not showing any messages because there's no messages in this room yet and we want to check our debug console and now we can see that we unsubscribe from channel private chat one we vacated and now we've subscribed to a channel private chat too and it's currently occupied so that's perfect that's exactly what we're looking for when we leave one channel we unsubscribe from any notifications and we subscribe to the new channel notifications let's go back over to laravel and at this point everything should be connected and working the only thing we haven't tested is two users talking back and forth in the browser so let's go ahead and do that now i'm gonna use a different browser for this and for that i brought up safari so we don't actually have another user yet so i'm going to do register and i'm going to create a new user now that our new user is logged in let's go over to chat and we're currently in the tech talk channel so i'm going to switch over to tech talk and then let's zoom in so that we can see this and now i'm going to say something with this new user account and we're hoping to see it pop up over here on the screen so let's try this is a test great so our new user popped up automatically we didn't have to refresh the screen let's say something back from scriptster to our new user we'll say go subscribe now awesome so our chat is working we're able to send messages in both directions let's switch back to our general chat it switches out for both of our users we'll say hello and our new user popped up over here on my scriptster side and we'll say hello so at this point our chat application is all working we're able to send messages from multiple users in multiple chat rooms feel free to go in and change the stylization of this i didn't want to go crazy on css because i feel like that can really occupy a lot of the time and i really just wanted to show you guys how to get real-time chat working style this however you want use this as a template to build something even better maybe if you want go ahead and add the ability for users to create additional chat rooms we seeded these two chat rooms just to get started but maybe add a button allow them to create their own room give it a name and let them communicate in that new room if you haven't already go ahead like subscribe hit the little bell icon so you get notifications and i'll see you in the next video
Info
Channel: Scrypster
Views: 39,170
Rating: 4.9629974 out of 5
Keywords: Laravel, Laravel Sanctum, Jetstream, Jetstream Inertia, Inertia, PHP, Laravel PHP, Real-time chat, Chat App, Chat Application, Pusher, Pusher Web-sockets, Web-sockets, websockets, Pusher Websockets, Laravel Echo, Laravel pusher
Id: CkRGJC0ytdU
Channel Id: undefined
Length: 69min 33sec (4173 seconds)
Published: Fri Dec 04 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.