Real time private chatting app using Angular 2, Nodejs, mongodb and Socket.io – Part 4

This is a final and last part of the Building Real time private chatting app using Angular. In this part, we will build our application by adding features listed below,

  1. Fetching the conversation between users when any user will be selected from the list.
  2. We will add the real-time chat feature.
  3. Implementing the Logout feature.

A little recap again, To integrate the real-time morality in our application we connected our Angular application to Socket Server. Later we implemented the Realtime chat list for the application. On the server side, we wrote Socket Server Event to Emit the updated Chat List. And at the end, we Highlighted the select user from the list of users.

The last thing we did in third part was highlighting a selected user from the chat list to start a new chat. We will start our implementation from where we left in the last part. So let’s start the implementation,

 

     Download

     Demo

 




 

Fetching the conversation between users

As the title reads Fetching the conversation between users, it seems very easy, right! All you have to do is make an HTTP call and you are done. Well, this is exactly what you are going to do but there is a little problem.

ChatListComponent is a separate component and the ConversationComponent will be a separate Component, which we will create in next few minutes. So here you here you have to pass data between two sibling component.

Also read, Passing data between Angular 2 Components

So first we will create Conversation Component and then we will display messages and do other things. As always I will divide this section into smaller chunks and this way we will speed the development of this application.

Creating Conversation Component

Let’s create Conversation Component nothing so special about it. Execute the below Angular CLI commands.

The First command to create Conversation Module,

Then the second Will generate the Actual Component,

Now your  Conversation component is ready to use, So why wait let’s import it into  Home component  and see if it works!

Open the home.component.ts and add the below line,

home.component.ts:

Now you can add the <app-conversation> into your home.component.html file, and it should show the traditional conversation works! message. So at this point, your home.component.html file should look like this.

home.component.html:

Sharing the data with a sibling Component

This part can be a pain for newbie developers, but it shouldn’t be actually. We can create a service and which will just share the data between different component.

As of now in this I won’t go into details, we will just write down the code for our Component classes. Again read this article, Passing data between Angular 2 Components and understand how to pass data between components.

So I have found this GIST, which does the same thing. Read and understand it, and again I have added this service to our boilerplate. So you don’t have to worry about that, just worry about component classes and HTML.

We will rewrite home.component.html. Why? Because we will add inputs to the <app-chat-list> and <app-conversation> components. So just update markup inside the <main> tag by below markup.

home.component.html:

Explanation:

In the above code,

  1. The conversation input will carry the conversation between the two users.
  2. The selectedUserInfo input will carry tha data of the selected user from the list of users.

Also, do not forget to add the below properties in HomeComponent class. If you don’t add property shown below, then the key inside the Emitter service will be undefined and then you will have a problem later.

And you will understand the above line only if you read this GIST.

Now your components can share the data, but can not read them. Why? because your component is neither listening to them not Emitting them. So to achieve this add the input properties in ChatListComponent class and HomeComponent class.

Add the below properties in both the files conversation.component.ts and chat-list.component.ts.

conversation.component.ts | chat-list.component.ts:

Send data of the selected user from the list of user to conversation Component

This is just a continuation of the last section. Here, we will select a user from the list of users. And we will send the details of that selected user, to conversation component as the above title reads.

Will have to add only 3 lines of code to accomplish this and the code will be added inside the selectedUser() method of chat-list.component.ts.

chat-list.component.ts:

Explanation:

  1. The above code is very easy to understand, so we won’t even talk about the first line of the method.
  2. The second line is kinda interesting for us since it would emit the data to the other component.
  3. Yes, by using EmitterService we will emit the user parameter and that we will read inside the ConversationComponent class.

This was the part where you send data, now let’s read the incoming the from a different component. Here we will take help of Angular Lifecycle hook method ngOnChanges().

So open the conversation.component.ts file and add the below method,

Explanation:

We have subscribed to get() of EmitterService, which will emit the event whenever any new user will be selected from the list of users.

Also, add the below property to the ConversationCompoenent class. Otherwise, where you will store the selected user’s information?

conversation.component.ts:

Well at this point you have information of the selected user from the list of users. you will use this information later while sending messages.

So this idea is really useful when you want to send data between sibling components. I hope we are on the same page till now if you have any doubts do let me know in below comments box.

Fetching the conversation between users from the server

It’s a general thinking that; when you click on any user from the chat list you would like to see the conversation between you and that user. This part is also going to be the same as the previous part, We will again send the conversation from ChatlistComponent class to ConversationComponent class.

But before all this, we will make an HTTP call to fetch the conversation between the user from the server. So to do this we will use the getMessages() method. This method is defined inside the ChatService class.

So open the chat-list.component.ts and write down the below code,

chat-list.component.ts:

Explanation:

  1. So the first thing first we made an HTTP call to fetch the conversation from the server.
  2. The method getMessages() requires userId (logged in user) and the toUserId (user selected from the chat list).
  3. Later we emit the response received from the server to ConversationComponent class and then ConversationComponent class renders the messages as a chat between users.

Let’s write a Nodejs express Route to return the response when we try to fetch the response from /getMessages route. Open the routes.js and add the below route to it,

routes.js:

As you can see, we have called getMessagesRouteHandler() method to handle the request and response for this route. So as always, it will send an appropriate response based on the result from the database.

Open the route-handler.js and the below method into it,

route-handler.js:

Explanation:

  1. First, we validated the request parameters and based on that server returns the response.
  2. Then inside the else block, we fetch the messages from MongoDB by calling getMessages() method.
  3. If all goes as expected then we return a response to messages.

Now let’s fetch data from database using MongoDB query. Here I expect from you that you are familiar with MongoDB queries.

Open the query-handler.js file and add the below method, this method will basically fetch the messages from the MongoDB.

query-handler.js:

Explanation:

  1. The first and most important thing here is the MongoDB query. It’s a combination of or and operators, which will basically give the required result.
  2. And then we return a Promise, which resolves a query result.

And that’s it.

Rendering the conversation as a chat messages

In my opinion this the easiest thing to do, so first thing first you gotta catch the emitted response from the ChatListComponent classs. So how do we do that?Just like the last section writing something inside the ngOnChanges() method.

But first, add the below code properties inside the ConversationComponent class.

conversation.component.ts:

Now open the conversation.component.ts and add the below code to the ngOnChanges() method. The below code seems fairly easy to understand, just assigning values to component properties.

conversation.component.ts:

Now, if anything is left then that would be only HTML. So writing HTML will be the piece of cake for us since we already have everything in out component class.

Open the conversation.component.html and the below markup,

conversation.component.html:

Explanation:

  1. First, there will be an overlay on the Conversation Component, till you select any user from the chat list.
  2. Once you will select a user from the chat list, then we will show a message saying that; You are chatting with someone, for example, Chatting with Shashank
  3. Then we have *ngFor to render the messages using messages property from the ConversationComponent class.
  4. alignMessage() method will align the messages to left or right based on the user id of the user.

Now if you look at your screen you should see something similar to the below image,

Real time private messaging chatting app using Angular 2, Nodejs, mongodb and Socket.io

Chat between two users

Sending and Receiving Real-time messages

Finally! The last and the final puzzle of the application, here first we will send a message to the selected user from the chat list and we will write a code to listen for the incoming messages from the server.

So basically we will divide this section into two parts. In the first part we will write code to send the message and In the second part, we will write code to receive the messages.

Sending real-time messages

So let’s start with the markup open the conversation.component.html and write the below code beneath the div tag having .massege-typer class.
conversation.component.html:

Here we don’t have too much to understand except keyup Event. In the keyup event, we will send the message to the server when the key code will be 13.

In less technical term when user will press enter button we will send the message to the server.

In the conversation.componet.ts file, we have defined the sendMessage() which will send the message to the server. So open the  conversation.componet.ts file and add the below method,

conversation.componet.ts:

Explanation:

  1. First, we check for the validation. If anything goes wrong with that then we show the alert.
  2. After that we inside else block, We have prepared a data to send to the other user.
  3. Also, we will push this data into existing messages array.
  4. Next, we actually send this data to Nodejs server by calling sendMessage() method, Which basically emits the socket event.
  5. And at end, we scroll the scrollbar to the bottom.

All this work that we just did; is incomplete without writing the nodejs socket event. And also we need to save these messages in MongoDB.

The below socket event will listen to the socket event and based on the user’s id it will send messages to the recipients. Since it’s a socket event that we are emitting from Angular, So open the socket.js and ad the below code,

socket.js:

Explanation:

  1. The first thing would be validation, check if everything is okay. If all goes well then we will go ahead and do the further operation.
  2. Inside the else block, we are calling two methods getUserInfo() and insertMessages(); both these methods are defined inside the QueryHandler class.
  3. getUserInfo() method will fetch socket id of the user who is intended to receive a message and the insertMessages() method as the name suggests will store the messages into a database.
  4. And at the end, we will emit an event with the data and this data is nothing but the data received in the add-message event.

Receiving Real-time messages

Ah! this part is damn so easy to implement. Here we will use two components HomeComponent and ConversationComponent, just like we did in last part.

In other words, we will call a method named as listenForMessages() from HomeComponent to listen for incoming messages from the socket server; and the listenForMessages() method will be defined inside the ConversationComponent.

Once you call this method, it will listen to the incoming messages and automatically show the new messages. So open the home.compotent.ts and add the below inside the ngOnInit() method,

home.compotent.ts:

If you notice I have passed the user id of the user as a parameter; that user id will be used while sending messages.

Now the real magic will happen inside the ConversationComponent class. So open the conversation.component.ts and add the below code to it,

conversation.component.ts:

Explanation:

  1. The user id is used while sending the messages, so first thing first we took care of it.
  2. Then we will call receiveMessages() method which defined inside the SocketService class.
  3. Once you receive a new message, you will add that message into the this.messages property of the ConversationComponent class.
  4. And then again, we will move the scroll bar to bottom as a tradition.

Implementing Logout

Implementing Logout, yeah that the last thing is left to do. So here we will basically work only in HomeComponent Class. I really don’t need to give an overview of Logout functionality.

So let’s just hop into home.component.html add the below markup, and make sure your header looks like below markup,

home.component.html:

Now open the home.component.ts and the below code. In this below, we will consume the SocketService to achieve this functionality.

home.component.ts:

Explanation:

  1. Inside the logout() method, we called removeLS() method, which is defined inside the ChatService class. This method will delete the all the data stored in local storage related to this application.
  2. Then After that, we have called Logout method from SocketService class. This method will send a socket event to the server.  This will change the online status to offline.

Now the last part of the puzzle is socket event that will change the status from online to offline. So open the socket.js and add the below event to it,

socket.js:

Explanation:

  1. The below line will modify the online status of the user by making a query into MongoDB database.
  2. After doing that this event will emit the information of the logged out user in order to update the chat list.
  3. And on the front end, Angular will change the online status of the user.

Final thoughts

If you are still with from the start and you followed each and every step, then pat yourself on your back. This series was too big but I thought it was worth writing it.

But the good thing is now you know, how to create a private chatting application in Angular 2 with minimum complexity, for now, that’s the end of this series. Use both the Angular boilerplate and Nodejs boilerplateI highly recommend it. If it doesn’t work for download the source code from GitHub for Angular as well as for Nodejs server and try to relate to each point.

If you have any suggestion, Question or feature request let me know in the below comment box, I would be happy to help. If you like this article, do spread a word about it and share with others.