Why is the users array empty and the messages are not rendering

Viewed 40

console.log("start of join") doesn't get output and the users array remains empty. The only thing that renders is the room name. However, the server is connected. There are no errors present either. I think my front-end and server are not communicating properly. "react-router-dom": "^6.3.0"

server.js

const express = require("express");
const http = require("http");
const socketio = require("socket.io");
const router = require("./router");
const cors = require("cors");



const { addUser, removeUser, getUser, getUsersInRoom } = require("./users");

PORT = process.env.PORT || 3000;

const app = express();
const server = http.createServer(app);
const io = socketio(server, {cors: {
    origin: "*",
    credentials: true
  }});

console.log("I am server file")

app.use(router);
app.use(cors());

io.on("connection", socket => {
    console.log("connected");

    socket.on("joinRoom", ({ name, room }) => {
        console.log("start of join")
        const { error, user } = addUser({ id: socket.id, name, room });
        if (error) {
            return;
        }
        console.log("joined");

        socket.emit("message", {
            user: "admin",
            text: `${user.name}, welcome to the room!`,
        });
        socket.broadcast.to(user.room).emit("message", {
            user: "admin",
            text: `${user.name} has joined to room.`,
        });

        socket.join(user.room);

        io.to(user.room).emit("roomData", {
            room: user.room,
            users: getUsersInRoom(user.room),
        });
    });

    socket.on("sendMessage", async (message, callback) => {
        const user = await getUser(socket.id);

        try {
            io.to(user.room).emit("message", { user: user.name, text: message });
            io.to(user.room).emit("roomData", {
                room: user.room,
                users: getUsersInRoom(user.room),
            });
            callback();
        } catch (err) {
            console.log(err.message);
        }
    });

    socket.on("disconnect", () => {
        const user = removeUser(socket.id);
        console.log("disconnected");

        if (user) {
            io.to(user.room).emit("message", {
                user: "admin",
                text: `${user.name} has just left!`,
            });
        }
    });
});

server.listen(PORT, () => {
    console.log(`Server has started on port ${PORT}...`);
});

users.js

const users = [];

const addUser = ({ id, name, room }) => {
    name = name.trim().toLowerCase();
    room = room.trim().toLowerCase();

    const existingUser = users.find(
        user => user.room === room && user.name === name
    );

    if (!name || !room) return { error: "Username and room are required." };
    if (existingUser) {
        return { error: "This username is already taken!" };
    }

    const user = { id, name, room };

    users.push(user);

    return { user };
};

const removeUser = id => {
    const index = users.findIndex(user => user.id === id);

    if (index !== -1) return users.splice(index, 1)[0];
};

const getUser = id => {
    for (let i = 0; i < users.length; i++) {
        if (users[i].id == id) return users[i];
    }
};

const getUsersInRoom = room => users.filter(user => user.room === room);

module.exports = { addUser, removeUser, getUser, getUsersInRoom };

Join.jsx

import React from "react";
import { useState } from "react";

import { Link } from "react-router-dom";

function Join() {
  
  const [name, setName] = useState("");
    const [room, setRoom] = useState("");



  return (
    <div className="joinOuterContainer">
        <div id="form-area">
                    <h1 className="heading">Join</h1>
                    <p className="join-phone">Sign in to join a room!</p>

                    <div>
            <input type="text" className="joinInput" onChange={e => {setName(e.target.value)}} spellCheck="false" required />
            <label>Name</label>
          </div>

          <div>
            <input type="text" className="joinInput" onChange={e => {setRoom(e.target.value)}} spellCheck="false" required />
            <label>Room</label>
          </div>

          <Link onClick={e => (!name || !room ? e.preventDefault() : null)}
                        to={`./chat?name=${name}&room=${room}`}>
                        <button className="button" type="submit">
                            Sign In
                        </button>
                    </Link>

          </div>
    </div>
  );
};

export default Join;

Chat.jsx

RowContent.jsx This is where the messages are rendered


import ScrollToBottom from "react-scroll-to-bottom";


const RowContent = ({
    message,
    setMessage,
    sendMessage,
    messages,
    name,
    room,
}) => {
    return (
        <div id="row-content-main-container">
            <div id="message-box">
                <Messages messages={messages} name={name} />
            </div>

            <form id="form">
                <input
                    type="text"
                    value={message}
                    placeholder="Type a message..."
                    onChange={event => setMessage(event.target.value)}
                    onKeyPress={event =>
                        event.key === "Enter" ? sendMessage(event) : null
                    }
                />
                <button onClick={event => sendMessage(event)}>
                    <h4>Send</h4>
                </button>
            </form>
        </div>
    );
};


const Messages = ({ messages, name }) => {
    return (
        <div className="message-box">
            {messages.map((message, i) => (
                <div key={i}>
                    <Message message={message} name={name} />
                </div>
            ))}
        </div>
    );
};

const Message = ({ message, name }) => {
    
    let isSentByTheCurrentUser = false;

    const trimmedName = name.trim().toLowerCase();
    console.log(message, name);

    if (message) {
        if (message.user === trimmedName) {
            isSentByTheCurrentUser = true;
        }
        if (isSentByTheCurrentUser) {
            return (
                <div className="message-container current-user-container">
                    <div className="message-box current-box">
                        <p className="sent-text">{message.text} </p>
                    </div>
                </div>
            );
        } else if (message.user === "admin") {
            return (
                <div className="message-container admin-user-container">
                    <div className="message-box admin-box">
                        <p className="sent-text sent-text-admin">{message.text} </p>
                    </div>
                </div>
            );
        } else {
            return (
                <div className="message-container other-user-container">
                    <div className="message-box other-box">
                        <p className="sent-by">{message.user}</p>
                        <p className="sent-text">{message.text} </p>
                    </div>
                </div>
            );
        }
    }
    return null;
};

export default RowContent;

RowUsers.jsx this is where the user list should be rendered, but my array is never updated

import ScrollToBottom from "react-scroll-to-bottom";

const RowUsers = ({ room, users }) => {
    return (
        
        <div id="row-users-main-container">

    <div id="row-users-header">
            <h1>{room}</h1>
            </div>
            <div id="users">
            {console.log(users)}


        <div className="users-container">
            <p>All Users:</p>
            {users.map((user, i) => (
                <div key={i}>
                    <div className="user-container">
                        <p>Username:</p>
                        <p>{user.name}</p>
                    </div>
                </div>
            ))}
        </div>



            </div>
            <div id="footer">
                <div id="logo-column">              
                    <h1>Simple Chat</h1>
                </div>
                <div id="leave-column">
                    <a href="/">
                        <h2>Leave</h2>
                    </a>
                </div>
            </div>
        </div>
    )
}

export default RowUsers;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

import { BrowserRouter as Router,Routes, Route } from "react-router-dom";
import Join from './Join';
import Chat from './Chat/Chat'

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    
    <Router> 
      <App />
      <Routes>
        <Route path="/" exact element={<Join/>} />
        <Route path="/chat" element={<Chat/>} />
      </Routes>

      </Router>
   
  </React.StrictMode>
);
0 Answers
Related