Chat App with WebSocket: Adding New User
Tags: javascript, webdev, react, node
Published: 2022-08-20 11:57:17

{% embed https://dev.to/sokhavuth/table-of-contents-3m2h %}
GitHub: [https://github.com/Sokhavuth/chat](https://github.com/Sokhavuth/chat)
Heroku: [https://khmerweb-chat.herokuapp.com/](https://khmerweb-chat.herokuapp.com/)
<br/>

<p>When a new user fill her/his name on the chat page, related socket client can emit information about this new user to socket server which in turn will broadcast a chat message to all socket clients to let them know that a new user has been joining the conversation.</p>

<p>Moreover, socket server could also register this new user in a collection object to be sent to all socket clients that will list all users in the collection object on their chat page. Socket clients can also emit an event to socket server when the user tries to change his/her chat name.</p>

```html
<!--index.html-->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Khmer Web Chat</title>
    <link rel="stylesheet" href="/base.css" />
    <link rel="stylesheet" href="/chat.css" />
    <link href="/fonts/setup.css" rel="stylesheet" />
    <link href="/logo.png" rel="icon" />
  </head>
  <body>
    <section class="Chat region">
        <div class="main">
            <div class="title">
                <input type="button" value="Leave chat" />
            </div>
            <div class="outer">
                <div id="msg-board"></div>
                <form action="" onSubmit="submitHandler(event)">
                    <input type="text" id="chat-name" onChange="onChange()"
                    required placeholder="Chat name" />
                    <input id="input" autocomplete="off" required 
                    placeholder="Type your message here" />
                    <input type="submit" value="Send" />
                </form>
            </div>
        </div>
        <div class="sidebar">
            <div class="title">All people</div>
            <div id="users" class="content"></div>
        </div>
    </section>

    <script src="/socket.io/socket.io.js"></script>
    <script>
        const socket = io();

        socket.on('connection', (userid) => {
            if(!localStorage.getItem('userid')){
                localStorage.setItem('userid', userid);
            }
        })

        function onChange(){
            const username = document.getElementById('chat-name');
            if(username.value){
                const obj = {
                    username: username.value,
                    userid: localStorage.getItem('userid'),
                }
                
                socket.emit('new user', obj);
            }
        }

        socket.on('new user', (obj) => {
            const msgBoard = document.getElementById('msg-board');
            let element = document.createElement('div');
            element.setAttribute("class", "new-user");
            const msg = `${obj.username} join the conversation`;
            element.textContent = msg;
            msgBoard.appendChild(element);
            element.scrollIntoView();

            const users = document.getElementById('users');
            users.innerHTML = '';
            for(let key in obj.users){
                element = document.createElement('div');
                element.setAttribute("class", "user");
                const user = obj.users[key];
                element.textContent = user;
                users.appendChild(element);
                element.scrollIntoView();
            }
        })

        function submitHandler(e){
            e.preventDefault();
            const input = document.getElementById('input');
            const obj = {
                userid: localStorage.getItem("userid"), 
                message: input.value,
            };

            if (input.value) {
                socket.emit('chat message', obj);
                input.value = '';
            }
        }

        socket.on('chat message', function(obj){
            const msgBoard = document.getElementById('msg-board');
            const element = document.createElement('div');
            const msg = `${obj.chatName}: ${obj.message}`;
            element.textContent = msg;
            msgBoard.appendChild(element);
            element.scrollIntoView();
        });
    </script>
  </body>
</html>
```

```js
// index.js
// npm install express
// npm install socket.io
// npm install nodemon

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const path = require('path');
const { Server } = require("socket.io");
const io = new Server(server);


const port = process.env.PORT || 3000;
app.use(express.static(path.join(__dirname, 'public')));

app.get('/', (req, res) => {
    res.sendFile(`${__dirname}/index.html`);
});

const users = {};
io.on('connection', (socket) => {
    const userid = Date.now() + Math.round(Math.random() * 1E9).toString();
    socket.emit('connection', userid);

    socket.on('new user', (obj) => {
        users[obj.userid] = obj.username;
        obj.users = users;
        io.emit('new user', obj);
    });

    socket.on('chat message', (obj) => {
        obj.chatName = users[obj.userid];
        io.emit('chat message', obj);
    });
});

server.listen(port, () => {
    console.log(`listening on *${port}`);
});
```