I'm trying to send a message to the receiver from frontend. As per backend it worked fine. But in frontend I had a pretty hard time to implement the backend code in the frontend to send a message to the receiver. I'll lend you my server side code and client side.
What I have tried:
Backend message.js
const express = require('express');
const router = express.Router();
const fetchuser = require('../middleware/fetchuser');
const Message = require("../models/Message");
router.post('/sendmessages/:userId', fetchuser, async (req, res) => {
const { receiver, text } = req.body;
const sender = req.user._id;
try {
const message = new Message({ sender, receiver, text });
await message.save();
res.json(message);
} catch (error) {
console.error(error);
res.status(500).json({ error: 'Server error' });
}
});
module.exports = router;
auth.js
const express = require('express');
const router = express.Router();
const User = require('../models/User');
const bcrypt = require('bcrypt');
const { body, validationResult } = require('express-validator');
const jwt = require("jsonwebtoken");
const JWT_SECRET = 'INFAMOUS';
const fetchuser = require('../middleware/fetchuser');
router.post('/signup', [
body('email').isEmail(),
body('password', 'Password should be atleast 6 characters').isLength({ min: 6 })
], async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { email, password } = req.body;
const salt = await bcrypt.genSalt(10);
const secPass = await bcrypt.hash(password, salt);
try {
const user = await User.findOne({ email });
if (user) {
return res.status(400).json({ message: 'A user already exists with this e-mail address' });
};
const newUser = new User({
email, password: secPass,
});
await newUser.save();
const token = jwt.sign({userId:newUser._id}, JWT_SECRET);
newUser.token = token;
res.status(201).json({ token, message: "Succssfully user created" });
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal server error" });
}
});
router.post('/login',[
body('email').isEmail(),
body('password', 'No Blank').exists()
], async(req, res)=> {
let success = false;
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { email, password } = req.body;
try {
const user = await User.findOne({ email });
if (!user) {
success = false;
return res.status(400).json({success, message: 'Not found user' });
};
const compare = await bcrypt.compare(password, user.password);
if(!compare) {
success = false;
return res.status(400).json({success, error: "Enter corretly"});
}
const token = jwt.sign({userId: user._id}, JWT_SECRET);
success = true;
res.status(201).json({ success, token, message: "Succssfully loginn" });
} catch (error) {
console.log(error);
res.status(500).json({ message: "Internal server error" });
}
})
router.post('/getuser', fetchuser, async (req, res) => {
try {
const userId = req.user._id;
const user = await User.findById(userId).select("-password");
res.send(user);
} catch (error) {
console.error(error.message);
res.status(500).send("Internal Server Error");
}
})
router.get('/allusers' , async (req, res) => {
await User.find({})
.then(users => {
const userFunction = users.map(user => {
const container = {}
container.email = user.email
return container
})
res.status(200).json({ user: userFunction })
})
.catch(err =>
res.status(401).json({ message: "Not successful", error: err.message })
)
})
router.post('/logout', async(req,res)=>{
try{
res.clearCookie('token');
res.status(200).json({success: true, message: 'Logout successfull'})
} catch (error) {
console.error(error);
res.status(500).json({success: false, message: 'Internal server error'});
}
})
module.exports = router
index.js
const express = require('express');
const db = require('./db');
const cors = require('cors');
const socketio = require('socket.io');
const app = express();
const http = require('http');
const server = http.createServer(app);
const io = socketio(server, {
cors: {
origin: 'http://localhost:3000',
methods: ['GET', 'POST'],
},
});
const port = 5000;
db();
app.use(cors());
app.use(express.json());
app.use('/api/auth', require('./routes/auth'));
app.use('/api/message', require('./routes/message'));
io.on('connection', (socket) => {
console.log(`User connected: ${socket.id}`);
socket.on('message', (data) => {
console.log(`New message from ${socket.id}: ${data}`);
});
socket.on('sendMessage', (data) => {
io.emit('message', data);
});
socket.on('disconnect', () => {
console.log('User disconnected');
});
});
server.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
fetchuser.js
const jwt = require("jsonwebtoken");
const JWT_SECRET = 'INFAMOUS';
const fetchuser = (req, res, next) => {
const token = req.header('auth-token');
if (!token) {
return res.status(401).send({ error: "Please authenticate using a valid token" })
}
try {
const data = jwt.verify(token, JWT_SECRET);
console.log('Decoded Token:', data);
req.user = { _id: data.userId };
next();
} catch (error) {
return res.status(401).send({ error: "Please authenticate using a valid token" })
}
}
module.exports = fetchuser;
Frontend Login.js
import axios from 'axios';
import React, {useState} from 'react'
import { useNavigate } from 'react-router-dom'
const Login = () => {
const [credentials, setCredentials] = useState({email: "", password: ""})
let navigate = useNavigate();
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await axios.post("http://localhost:5000/api/auth/login", {
email: credentials.email,
password: credentials.password
});
const json = response.data
console.log(json);
if (json.success){
sessionStorage.setItem('token', json.token);
navigate("/");
}
else{
alert("Invalid credentials");
}
} catch (error) {
console.error('Login failed:', error);
}
}
const onChange = (e)=>{
setCredentials({...credentials, [e.target.name]: e.target.value})
}
return (
<div>
<form onSubmit={handleSubmit}>
<div className="mb-3">
<label htmlFor="exampleInputEmail1" className="form-label">Email address</label>
<input type="email" className="form-control" name="email" value={credentials.email} onChange={onChange} id="email" aria-describedby="emailHelp"/>
<div id="emailHelp" className="form-text">We'll never share your email with anyone else.</div>
</div>
<div className="mb-3">
<label htmlFor="exampleInputPassword1" className="form-label">Password</label>
<input type="password" className="form-control" name="password" value={credentials.password} onChange={onChange} id="password"/>
</div>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
)
}
export default Login
Chat.js
import axios from 'axios';
import React, { useState, useEffect } from 'react';
import io from 'socket.io-client';
const socket = io('http://localhost:5000');
const Chat = () => {
const [text, setText] = useState('');
const [messages, setMessages] = useState([]);
const [receiverOptions, setReceiverOptions] = useState([]);
const [receiver, setReceiver] = useState('');
const [senderUserId, setSenderUserId] = useState('');
useEffect(() => {
const fetchData = async () => {
try {
const authToken = sessionStorage.getItem('token');
console.log('Auth Token:', authToken);
if (authToken) {
const response = await axios.post('http://localhost:5000/api/auth/getuser', null, {
headers: {
'auth-token': `Bearer ${authToken}`
}
});
const userId = response.data._id;
setSenderUserId(userId);
}
const usersResponse = await axios.get('http://localhost:5000/api/auth/allusers');
setReceiverOptions(usersResponse.data.user);
} catch (error) {
console.error('Error fetching user or users:', error);
}
};
fetchData();
}, []);
useEffect(() => {
if (senderUserId) {
socket.on('message', (message) => {
setMessages((prevMessages) => [...prevMessages, message]);
});
}
}, [senderUserId]);
const handleSubmit = async (event) => {
event.preventDefault();
try {
if (!senderUserId) {
console.error('Sender User ID is empty or undefined.');
return;
}
const response = await axios.post(`http:
receiver,
text
}, {
headers: {
'auth-token': `Bearer ${sessionStorage.getItem('token')}`
}
});
const json = response.data;
console.log('Message sent successfully:', json);
socket.emit('sendMessage', {
sender: senderUserId,
receiver,
text,
});
setText('');
} catch (error) {
console.error('Error sending message:', error);
}
};
return (
<>
<div>
<form onSubmit={handleSubmit}>
<select value={receiver} onChange={(event) => setReceiver(event.target.value)}>
<option value="" disabled>Select a user</option>
{receiverOptions.map((user) => (
<option key={user.email} value={user._id}>{user.email}</option>
))}
</select>
<input type="text" value={text} placeholder="Your message" onChange={(event) => setText(event.target.value)} />
<button type="submit">Send</button>
</form>
<ul>
{messages.map((message, index) => (
<li key={index}>
{message.receiver}: {message.text}
</li>
))}
</ul>
</div>
</>
);
};
export default Chat;