Create a Chat Application Reactjs and Nodejs

creating a chat application using the MERN stack (MongoDB, Express.js, React.js, and Node.js)

Folder Structure:

- chat-app
  - backend
    - controllers
    - models
    - routes
    - server.js
  - frontend
    - public
    - src
      - components
      - App.js
      - index.js

Backend (Node.js/Express.js):

  1. Create backend/server.js file:
const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
const cors = require('cors');

// Middleware
app.use(cors());

// Socket.io
io.on('connection', (socket) => {
  console.log('A user connected');

  socket.on('chat message', (msg) => {
    io.emit('chat message', msg);
  });

  socket.on('disconnect', () => {
    console.log('A user disconnected');
  });
});

const PORT = process.env.PORT || 5000;

http.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});
  1. Create backend/routes/chat.js file for handling API routes:
const express = require('express');
const router = express.Router();

// Add your chat routes here

module.exports = router;
  1. Create backend/models/Message.js file for defining the Message schema:
const mongoose = require('mongoose');

const messageSchema = new mongoose.Schema({
  text: {
    type: String,
    required: true,
  },
  sender: {
    type: String,
    required: true,
  },
  timestamp: {
    type: Date,
    default: Date.now,
  },
});

module.exports = mongoose.model('Message', messageSchema);
  1. Create backend/controllers/chatController.js file for handling chat-related logic:
const Message = require('../models/Message');

// Example API endpoint
const getMessages = async (req, res) => {
  try {
    const messages = await Message.find().sort('-timestamp');
    res.json(messages);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: 'Server error' });
  }
};

module.exports = { getMessages };
  1. Update backend/server.js to use the chat route and connect to MongoDB:
const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
const cors = require('cors');
const mongoose = require('mongoose');

// Middleware
app.use(cors());

// Connect to MongoDB
mongoose.connect('mongodb://localhost/chat_app', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useCreateIndex: true,
});

const connection = mongoose.connection;
connection.once('open', () => {
  console.log('Connected to MongoDB');
});

// Socket.io
io.on('connection', (socket) => {
  console.log('A user connected');

  socket.on('chat message', (msg) => {
    io.emit('chat message', msg);
  });

  socket.on('disconnect', () => {
    console.log('A user disconnected');
  });
});

// Routes
const chatRouter = require('./routes/chat');
app.use('/chat', chatRouter);

const PORT = process.env.PORT || 5000;

http.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Frontend (React.js):

  1. Update frontend/src/App.js:
import React, { useEffect, useState } from 'react';
import io from 'socket.io-client';

const socket = io('http://localhost:5000');

function App() {
  const [messages, setMessages] = useState([]);
  const [messageInput, setMessageInput] = useState('');

  useEffect(() => {
    // Event listener for new messages
    socket.on('chat message', (msg) => {
      setMessages((prevMessages) => [...prevMessages, msg]);
    });

    // Clean up socket connection
    return () => {
      socket.disconnect();
    };
  }, []);

  const handleSendMessage = (e) => {
    e.preventDefault();

    if (messageInput.trim() !== '') {
      socket.emit('chat message', messageInput);
      setMessageInput('');
    }
  };

  return (
    <div>
      <ul>
        {messages.map((msg, index) => (
          <li key={index}>{msg}</li>
        ))}
      </ul>
      <form onSubmit={handleSendMessage}>
        <input
          type="text"
          value={messageInput}
          onChange={(e) => setMessageInput(e.target.value)}
        />
        <button type="submit">Send</button>
      </form>
    </div>
  );
}

export default App;
  1. Update frontend/src/index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Leave a Comment

Skip to content