• Download
  • Contact
  • Terms of Service
  • Privacy Policy
  • About US
Codershood
  • Demos
  • Plugins
  • Angular
  • NodeJs
  • GO lang
  • Others
No Result
View All Result
Codershood
  • Demos
  • Plugins
  • Angular
  • NodeJs
  • GO lang
  • Others
No Result
View All Result
Codershood
No Result
View All Result

Real Time chatting app using Nodejs, Mysql, AngularJs and Socket.io – Part 3

by Shashank Tiwari
August 8, 2018
in NodeJs
14
6 Minutes Read
Realtime chat system using nodeJs,Socket and AngularJs-part 3

In the First part, we created files required to set up for our Nodejs server and completed the Nodejs server setup, also in the first part we did the AngularJs setup for the application. After completing all the setup for Real Time chatting app, we created Login & Registration page.In the second part, we created a chat list features and wrote methods to display chat list. In this part, we will create real-time chatting feature between two players.

Here we will complete two features listed below,

  1. We will fetch messages between two users.
  2. Sending Messages between users (Real-time chatting feature)

 Download

 Demo

 


 

1. Fetching the messages between two users

So let’s start with the first point, so we will pick up from where we left in the last part and i.e. chat list feature. So the idea here is to click on any user displayed on chat list, should fetch the list of messages between logged in user and that user.

=>We will achieve that by passing the user Ids of those players.

=>We will register ang-clickfunction on the list of users as shown in below markup.

home.html:

<!-- 
    Real Time chatting app 
    @author Shashank Tiwari 
-->
<!-- Chat list Markup starts -->
<div class="col-md-4">
    <div class="chat-list-container">
        <p class="chat-list-heading"><i class="fa fa-list" aria-hidden="true"></i> <span >Chat list</span> </p>
        <div class="chat-list">
            <ul class="list-group" ng-if="data.chatlist.length > 0">
                <li class="list-group-item"
                    ng-repeat="friend in data.chatlist"
                    ng-click="selectFriendToChat(friend.id)" <!-- Added a ng-click() function -->
                    ng-class="{'active':friend.id == data.selectedFriendId}"
                >{{friend.username}}</li>
            </ul>
            <div class="alert alert-info" ng-if="data.chatlist.length === 0">
                <strong>No one is online to chat, ask someone to Login.</strong>
            </div>
        </div>                    
    </div>
</div>
<!-- Chat List Markup ends -->

Inside theselectFriendToChat()function, we will do two things. First, we will highlight the user selected from the list and second, we will make the HTTP call to get the messages between users.

=>To do that we have to write a function inside the home controller, which will do both the things.

=>Open thehome.controller.jsand write down below function.

home.controller.js:

/**
* Real Time chatting app
* @author Shashank Tiwari
*/
'use strict';

$scope.selectFriendToChat = (friendId) => {
    /*
    * Highlighting the selected user from the chat list
    */    const friendData = $scope.data.chatlist.filter((obj) => {
        return obj.id === friendId;
    });
    $scope.data.selectedFriendName = friendData[0]['username'];
    $scope.data.selectedFriendId = friendId;
    /**
    * This HTTP call will fetch chat between two users
    */    appService.getMessages(UserId, friendId).then( (response) => {
        $scope.$apply(() => {
            $scope.data.messages = response.messages;
        });
    }).catch( (error) => {
        console.log(error);
        alert('Unexpected Error, Contact your Site Admin.');
    });
}

When a client makes this HTTP call, on the server side we must have something to take care of this call. So we will write a route to handle this HTTP call also we will write the query to fetch messages from the database.

=>Open theroutes.jsfile and write down the below code.

=>In the below code we are consuminggetMessages()method ofHelperclass to fetch the messages from the database.

/**
* Real Time chatting app
* @author Shashank Tiwari
*/
'use strict';

this.app.post('/getMessages',async (request,response) => {
    const userId = request.body.userId;
    const toUserId = request.body.toUserId;
    const messages = {}
    if (userId === '') {
        messages.error = true;
        messages.message = `userId cant be empty.`;
        response.status(200).json(messages);
    }else{
        const result = await helper.getMessages( userId, toUserId);
        if (result ===  null) {
            messages.error = true;
            messages.message = `Internal Server error.`;
            response.status(500).json(messages);
        }else{
            messages.error = false;
            messages.messages = result;
            response.status(200).json(messages);
        }
    }
});

Now moving over to Helper class here, we have to write MySql query to fetch data from the database. The below is wrapped inside the async/await function as show below.

helper.js:

/**
* Real Time chatting app
* @author Shashank Tiwari
*/
'use strict';

async getMessages(userId, toUserId){
    try {
        return await this.db.query(
            `SELECT id,from_user_id as fromUserId,to_user_id as toUserId,message FROM message WHERE 
                (from_user_id = ? AND to_user_id = ? )
                OR
                (from_user_id = ? AND to_user_id = ? )ORDER BY id ASC
            `,
            [userId, toUserId, toUserId, userId]
        );
    } catch (error) {
        console.warn(error);
        return null;
    }
}

2. Sending Messages between users (Real-time chatting feature)

Here I would like to divide this topic into two parts.The first part issending the messagesand the second will be thereceiving the messagesfrom the socket server. And we will learn both of them one by one.

1. Sending the messages

Now, this features completely relies on the socket Events. If server emits any event then the client will respond to it accordingly. If you are not new to socket programming then you must be aware of how things work here. But for those who don’t know much about it, I will explain here anyway.

=>So here we will implement a real-time chat between users by sending an event from the client.

=>When the server receives the emitted request from client then it responds back to the client to whom we are willing to send a message.

=>In our case, we will pass the socket id to server and server will emit the event only to that socket id.

=>Let’s start with the markup, Open thehome.htmland add the below markup to it,

home.html:

<!-- 
    Real Time chatting app 
    @author Shashank Tiwari 
-->
 <!-- Message Area Markup starts -->
<div class="col-md-8">
    <div class="message-container">
        <p ng-show="data.selectedFriendId !== null" ? true : false >
            <i class="fa fa-envelope" aria-hidden="true"></i>
            <span class="message-heading"> Chat History With {{data.selectedFriendName}}</span>
        </p>
        <div class="message-list">
            <ul class="message-thread">
                <li ng-repeat="messagePacket in data.messages"
                    ng-class="{ 'align-right' : alignMessage(messagePacket.fromUserId) } ">
                    {{messagePacket.message}}
                </li>
            </ul>
        </div>
        <div class="message-text">
            <textarea id="message" 
                class="message form-control" 
                placeholder="Type and hit Enter" 
                ng-keydown="sendMessage($event)"
            ></textarea>
        </div>
    </div>
</div>
<!-- Message Area Markup ends -->

Explanation:

In the above markup, three important things are happening, which are listed below.

  1. First, when you select a user from chat list, we show a dialog asChat History With ####. Nothing complicated with it just anAngularJsmodeland that’s it.
  2. Below to that, we will have a list of messages, which can be rendered usingdata.messagesmodel usingng-repeat.
  3. As I explained in above, How wefetch messages from the serverby makingHTTP call.
  4. Now when we receive messages from the server by making HTTP call, we assign new messages to thisdata.messagesmodel which renders the messages.
  5. And at the end, we have we havetextareato write messages and we have set up akeydownlistener to send messages.
  6. After writing messages, when user will press enter button message will be sent through socket.io.

We wrote markup to send messages, but to make work them we’ll have to write some AngularJs. For the above markup, we already wrote the AngularJs for them in the previous section. Inside theselectFriendToChat()we have written the half of the above markup. So we will focus on only sending messages part. Open thehome.controller.jsand write down the below code,

home.controller.js:

/**
* Real Time chatting app
* @author Shashank Tiwari
*/
'use strict';

$scope.sendMessage = (event) => {

    if (event.keyCode === 13) {

        let toUserId = null;
        let toSocketId = null;

        /* Fetching the selected User from the chat list starts */        let selectedFriendId = $scope.data.selectedFriendId;
        if (selectedFriendId === null) {
            return null;
        }
        friendData = $scope.data.chatlist.filter((obj) => {
            return obj.id === selectedFriendId;
        });
        /* Fetching the selected User from the chat list ends */        
        /* Emmiting socket event to server with Message, starts */        if (friendData.length > 0) {

            toUserId = friendData[0]['id'];
            toSocketId = friendData[0]['socketid'];            

            let messagePacket = {
                message: document.querySelector('#message').value,
                fromUserId: UserId,
                toUserId: toUserId,
                toSocketId: toSocketId
            };
            $scope.data.messages.push(messagePacket);
            appService.socketEmit(`add-message`, messagePacket);

            document.querySelector('#message').value = '';
            appService.scrollToBottom();
        }else {
            alert('Unexpected Error Occured,Please contact Admin');
        }
        /* Emmiting socket event to server with Message, ends */    }
}

Explanation:

In the above function, we are doing three main things,

  1. First, here we are extracting the selected friend’s information to send messages.
  2. Then we create a message packet and send it to the socket server also we push the message packet to thedata.messagesmodel to render it on the screen.
  3. Then we scroll the div which displays the messages to the bottom.

I assume that you understand the purpose of this block and if you have any questions please comment below, I’ll help in that. Now it’s time to write server-side socket events.

=>Now we will write a socket event in order to listen to messages on the server side and accordingly will send a response back to the server.

=>Once the server receives the event it will store messages to the database, by executing the MySql queries.

=>In the below code, we are callinginsertMessages() method of the Helper class, which will store the messages into MySql database.

=>Then we send message data to the corresponding user by emitting the socket event. Open thesocket.jsfile and write down the below code,

socket.js:

/**
* Real Time chatting app
* @author Shashank Tiwari
*/
'use strict';

/**
* send the messages to the user
*/socket.on('add-message', async (data) => {
    
    if (data.message === '') {
        
        this.io.to(socket.id).emit(`add-message-response`,`Message cant be empty`); 

    }else if(data.fromUserId === ''){
        
        this.io.to(socket.id).emit(`add-message-response`,`Unexpected error, Login again.`); 

    }else if(data.toUserId === ''){
        
        this.io.to(socket.id).emit(`add-message-response`,`Select a user to chat.`); 

    }else{                    
        let toSocketId = data.toSocketId;
        const sqlResult = await helper.insertMessages({
            fromUserId: data.fromUserId,
            toUserId: data.toUserId,
            message: data.message
        });
        this.io.to(toSocketId).emit(`add-message-response`, data); 
    }               
});

Open thehelper.jsfile and write down the below code. In the below code, we execute MySql insert query to store MySQL data nothing more than that.

helper.js:

/**
* Real Time chatting app
* @author Shashank Tiwari
*/
'use strict';

async insertMessages(params){
    try {
        return await this.db.query(
            "INSERT INTO message (`from_user_id`,`to_user_id`,`message`) values (?,?,?)",
            [params.fromUserId, params.toUserId, params.message]
        );
    } catch (error) {
        console.warn(error);
        return null;
    }
}

2. Receivingthe messages

In this small section, we will write the socket event handler for the receiving the socket event on the client side and which will be very easy. Open thehome.controller.jsand write down below code we will do listed things below,

=>We will userscoket.ona method to handle the socket event and receive the messages.

=>After receiving the messages we will display them usingdata.messagesmodel.

=> You will add this code inside thehome.controller.js, just below to the chat list code.

home.controller.js:

/**
* Real Time chatting app
* @author Shashank Tiwari
*/
'use strict';

/*
* This eventt will display the new incmoing message
*/appService.socketOn('add-message-response', (response) => {
    $scope.$apply( () => {
        if (response && response.fromUserId == $scope.data.selectedFriendId) {
            $scope.data.messages.push(response);
            appService.scrollToBottom();
        }
    });
});

Final thoughts

Now you know, how to create a private chatting application in AngularJs with minimum complexity, for now, that’s the end of this series. If you want toreport an issue, you can use GitHub for that, I have uploaded thecode to the GitHub. Using GitHub will be very easy for all of us to track all the issues.

Alos, If you like this article consider sharing this on your social account with other people as well. You can suggest or request an article on any topic I would love write it for you.

If you have any suggestion or Question let me know in the below comment box and If you like this article share with others.

 

 

 

Tags: Angular chatAngular socket.ioAngularJsChatDatabaseExpressMySqlNodejsNodejs ServerRealtime chatsocket.io
Previous Post

Real Time chatting app using Nodejs, Mysql, AngularJs and Socket.io – Part 2

Next Post

Typing notification in chatting application using nodejs and socket.io

Related Posts

Create your first Blockchain using Nodejs Blockchain
NodeJs

Create your first Blockchain using Nodejs

September 12, 2018
Detect Faces in Images using Nodejs
NodeJs

Detect Faces in Images using Nodejs

August 8, 2018
Creating API Rate limiter in Nodejs using express and Redis
NodeJs

Creating API Rate limiter in Nodejs using express and Redis

August 8, 2018
Next Post
Typing notification in chatting application using nodejs and socket.io

Typing notification in chatting application using nodejs and socket.io

Comments 14

  1. Fozil Umarov says:
    9 years ago

    Hello! I want to integrate a chat on my site.Site placed on the YII framework. What do you advise ?

    Reply
  2. MEysaM Arab says:
    9 years ago

    Hi!
    please check demo, not working!!

    Reply
  3. Dalton Luis Boer says:
    9 years ago

    This Demo not work

    Reply
  4. Javier says:
    9 years ago

    I’m getting the code instead of the query result in the home page after login.
    {{send_to_user_name==” ? ‘Select User to Chat’: send_to_user_name}}

    All the .js & css are on the right directory.

    Could you help me with that?

    https://uploads.disquscdn.com/images/9eb1cf6c51f73bea2b20d42d3a24bc267a13647c3d19ab7e5bea396094125144.png

    Reply
    • Shashank says:
      9 years ago

      hii Javier,

      Make sure you don’t have any errors in js file,open the console try to resolve those error.

      Reply
  5. J Blake says:
    9 years ago

    For some reason I can’t open the zip file. Can you please zip the file again? thanks.

    Reply
  6. varun ajmera says:
    8 years ago

    nice one. that i wanted man. 🙂
    @ShankyTtiwari:disqus

    Reply
    • Shashank says:
      8 years ago

      Thank you 😀

      Reply
      • varun ajmera says:
        8 years ago

        whenever i refresh socket.id is changed ? why?

        Reply
        • Shashank says:
          8 years ago

          Useful links for you.

          1. http://stackoverflow.com/questions/20260170/handle-browser-reload-socket-io

          2. http://stackoverflow.com/questions/9528845/how-to-avoid-create-a-new-socket-connection-in-socket-io-after-html-page-refresh

          Reply
  7. varun ajmera says:
    8 years ago

    @ShankyTtiwari:disqus many time socket.id is generating same id for multiple users why? in nodejs

    Reply
    • Shashank says:
      8 years ago

      many time socket.id is generating same id for multiple users That’s very Rear in my knowledge. If you are thinking to use socket id as unique user id then please don’t do that.

      Some Useful links for you.

      1. http://stackoverflow.com/questions/20962970/how-unique-is-socket-id
      2. http://stackoverflow.com/questions/15989514/can-you-rely-on-socket-id-as-a-uid

      Reply
  8. kipldeveloper says:
    8 years ago

    Can we send files in this chat application?

    Reply
    • Shashank says:
      8 years ago

      Yes,we can. If I have to do that I would do that something like this,
      1. I will upload files on the server.
      2.Then in messages I will send the path of the file with the file extension and take appropriate action (for ex, showing Image/video or audio tag)

      Hope this helps you.

      Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *




https://codershood.info

www.codershood.info programming blog dedicated to providing high-quality coding tutorial and articles on web development, Angular, React, Laravel, AngularJs, CSS, Node.js, ExpressJs and many more. We also provide ebook based on complicated web application along with the source code.

  • Download
  • Contact
  • Terms of Service
  • Privacy Policy
  • About US

www.codershood.info is licensed under a Creative Commons Attribution 4.0 International License.

No Result
View All Result
  • Demos
  • Plugins
  • Angular
  • NodeJs
  • GO lang
  • Others

www.codershood.info is licensed under a Creative Commons Attribution 4.0 International License.