Run socket.io from an express route - express

I have researched on this but nothing seems to satisfy my need. I have an express route connected to a mongodb. Below is part of the code.
const express = require('express');
const socketIo = require("socket.io");
const dbconnect = require("./models");
const handle = require("./handlers");
const routes = require("./routes");
const app = express();
app.use('/messages', routes.messages);
const PORT = 3000;
const server = app.listen(3000, function() {
console.log(`Listening on 3000`);
dbconnect().then(() => {
console.log("MongoDb connected");
});
});
const io = socketIo(server);
io.on('connection', function(client) {
console.log('Connected...');
});
My route looks like this:
const router = require('express').Router();
const handle = require('../handlers/messages');
router.post('/unread_messages', handle.unread_messages);
module.exports = router;
My handler looks like this:
const db = require("../models");
exports.unread_messages = async (req, res, next) => {
try {
const unreadmessages = await db.messages.countDocuments({ $and: [{receiver: req.body.receiver},
{ messageread: false }]});
return res.json({ unreadmessages });
} catch (err) {
return next({ status: 400, message: `Cannot get unread messages ${err}` });
}
};
I would like to add socket to the "/unread_messages" route so that I get an update of the count of unread messages in realtime. How do I do that?

Related

getting Can't find / on this server while deploying my app on localhost

when I tried to connect my application with API I'm getting error in my localhost saying
"status": "fail",
"message": "Can't find / on this server",
"error": { statusCode: 404, status: "fail", isOperational: true },
"stack": "Error: Can't find / on this server\n at C:\\Users/*/*app.js:66",
here is my app.js
const express = require("express");
const morgan = require("morgan");
const rateLimit = require("express-rate-limit");
const helmet = require("helmet");
const mongoSanitize = require("express-mongo-sanitize");
const xss = require("xss-clean");
const hpp = require('hpp');
const AppError = require("./API/Utils/appError");
const globalErrorHsndler = require("./API/controllers/errorController");
const usersRouter = require("./API/routes/usersRoute");
const app = express();
app.use(express.json({ limit: "10kb" }));
// DATA SANITIZATION against NoSQL query injection
app.use(mongoSanitize());
// DATA SANITIZATION against site script XSS
app.use(xss());
// PREVENT PARAMETER POPULATION
app.use(
hpp({
whitelist: [
"duration",
"difficulty",
"price",
"maxGroupSize",
"ratingsAverage",
"ratingsQuantity",
],
})
);
// SECURE HEADER HTTP
app.use(helmet());
//RATE LIMIT
const apiLimiter = rateLimit({
windowMs: 60 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: "Too many requests, please try again later"
});
// apply to specific routes
app.use("/api", apiLimiter);
app.use(morgan("dev"));
//CUSTOM MIDDLE WARE
app.use((req, res, next) => {
console.log("Hey i am from middleware function 👋");
next();
});
app.use((req, res, next) => {
req.requestTime = new Date().toISOString();
next();
});
app.use("/api/v1/users", usersRouter);
//ERROR SECTION
app.all("*", (req, res, next) => {
console.log(`Received request for url: ${req.originalUrl}`);
const error = new AppError(`Can't find ${req.originalUrl} on this server`, 404);
console.log(`Data inside next AppError: ${error}`);
next(error);
});
//GLOBAL ERROR HANDLEING
app.use(globalErrorHsndler);
module.exports = app;
here is my userRouter.js
const express = require("express");
const userControllers = require("./../controllers/userControllers");
const authController = require("./../controllers/authController");
const router = express.Router();
router.post("/signup", authController.signup);
router.post("/login", authController.login);
router.post("/forgotPassword", authController.forgotPassword);
router.patch("/resetPassword/:token", authController.resetPassword);
router.patch("/updateMyPassword", authController.protect, authController.updatePassword);
router.patch("/updateMe", authController.protect, userControllers.updateMe);
router.delete("/deleteMe", authController.protect, userControllers.deleteMe);
//ROUTERS USERS
router
.route("/")
.get(userControllers.getAllUsers)
.post(userControllers.createUser);
router
.route("/:id")
.get(userControllers.getSingleUser)
.patch(userControllers.updateUser)
.delete(userControllers.deleteUser);
module.exports = router;
and here is server.js
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const app = require("./app");
const next = require("next");
const port = process.env.PORT || 3000;
const dev = process.env.NODE_ENV !== "production";
const server = next({ dev });
const handle = server.getRequestHandler();
process.on("uncaughtException", err=>{
console.log("uncaughtException Shutting down Application");
console.log(err.name, err.message);
process.exit(1);
});
dotenv.config({ path: "./config.env" });
const DB = process.env.DATABASE.replace(
"<PASSWORD>",
process.env.DATABASE_PASSWORD
);
mongoose
.connect(DB, {
useCreateIndex: true,
useFindAndModify: false,
useNewUrlParser: true,
})
.then((con) => {
console.log("DB Connection Successfully");
})
server.prepare().then(() => {
app.get("*", (req, res) => {
return handle(req, res);
});
app.listen(port, () => {
console.log(`App running on port ${port}....`);
});
});
process.on("unhandledRejection", (err) => {
console.log("unhandledRejection Shutting down Application");
console.log(err.name, err.message);
server.close(() => {
process.exit(1);
});
});
I need to ask from experts as I'm new to this

cookie-session, socket.io fails to store socket.id in sessions

server.js
const express = require("express");
const cookieSession = require("cookie-session");
const socketIo = require("socket.io");
const app = express();
app.use(
cookieSession({
name: "session",
keys: ["key1", "key2"],
})
);
app.use((req, res, next) => {
console.log(req.session);
next();
});
app.get("/", (req, res) => {
res.sendFile("./index.html", { root: __dirname });
});
app.get("/about", (req, res) => {
const connectionId = req.session.connectionId;
res.send(`About. connectionId: ${connectionId}`);
});
const server = app.listen(1234);
const io = socketIo(server);
io.on("connection", (socket) => {
const connectionId = Math.random().toString(36).substring(2);
socket.request.session.connectionId = connectionId;
// socket.request.session.save();
});
My problem is that when I call the connect event on the client, but on the server socket.request.session returns undefined so I can't set a unique value in the cookie-session. What is it connected with?

how to pass req.params in a {mergeparams} for a post request express

I am trying to make a post request in a nested route but i keep getting 404 on postman.
app.js to handle my routes
app.use("/channel", controllers.channelController);
app.use("/channelentry", controllers.channelEntryController);
channelcontroller
const Express = require('express');
const router = Express.Router();
const channelEntry = require('./channelentrycontroller')
router.use('/:channelId', channelEntry)
channelEntryController
const Express = require('express');
const channelEntry = Express.Router({mergeParams: true});
channelEntry.get("/", async (req, res) => {
const channelId = req.params.channelId
try {
const messages = await models.ChannelEntryModel.findAll({
include: [{
model: models.ChannelModel,
where: { channelId: channelId }
}],
});
res.status(200).json({messages})
} catch (err) {
res.status(500).json({error: err})
}
});
channelEntry.post("/create", validateJWT, async (req, res) => {
const {entry} = req.body.channelentry
const channelId = req.params.channelId
const channelMessage = {
entry,
userId: req.user.userId,
channelId: channelId
}
try {
const currentChannelId = await models.ChannelModel.findOne({
where: {
channelId: channelId
}
})
const newChannel = await models.ChannelEntryModel.create(channelMessage, currentChannelId);
res.status(200).json(newChannel)
} catch (err) {
console.log(err)
res.status(500).json({error: err})
}
})
my get request works but sends an empty array because i have no entrys.
I ended up answering my own question.
I commented out:
app.use("/channelentry", controllers.channelEntryController);
I guess it was conflicting with my other route.

expressJS is preventing me to post a resource

I'm trying to build a mini app in express, the "database" I'm using is a local array object file, I can retrieve resources from this "database" but for some reason I'm not able to post (push) a new object to this object array. This is how the code looks like:
server.js:
const express = require('express');
const app = express();
const userRouter = require('./routes/user.js');
const port = process.env.PORT || 3000;
app.use(express.json());
app.use(express.text());
app.use('/user', userRouter);
app.listen(3000, () => console.log(`listening at ${port}`));
user.js:
const express = require('express');
const BBDD = require('./BBDD.js');
const userRouter = express.Router();
userRouter.get('/:guid', (req, res, next) => {
const { guid } = req.params;
const user = BBDD.find(user => user.guid === guid);
if (!user) res.status(404).send()
res.send(user);
next();
});
userRouter.post('/', (req, res, next) => {
let user = {};
user.name = req.body.name;
user.id = req.body.id;
BBDD.push(user);
next();
});
module.exports = userRouter;
And this is my local "database" file I want to perform logical CRUD operations:
BBDD.js
const BBDD = [{
index: 0,
guid: "1",
name: "Goku"
},
{
index: 1,
guid: "2",
name: "Vegeta"
},
];
module.exports = BBDD;
this is how I try to post a new resource, and this is the error I get:
It seems to be in order, but it won't work and can't find the bug.
Remove the next and send a response .express is having trouble finding the next matching handler because there is none

Express. Failed to load resource: the server responded with a status of 404

I am trying to make a post request using router.post and I keep getting " the server responded with a status of 404.
I have a routes folder with the file usersRoute.js :
const express = require("express");
const router = express.Router();
const User = require("../models/userModel");
router.post("/login", async(req, res) => {
const { username, password } = req.body;
try {
const user = await User.findOne({ username, password });
if (user) {
res.send(user);
} else {
return res.status(400).json(error);
}
} catch (error) {
return res.status(400).json(error);
}
});
router.post("/register", async (req, res) => {
try {
const newuser = new User(req.body);
await newuser.save();
res.send("User registered successfully");
} catch (error) {
return res.status(400).json(error);
}
});
module.exports = router;
I'm also using this method to make a get request to another endpoint in a carsRoute.js file which looks like this (the get request works) :
const express = require("express");
const router = express.Router();
const Car = require("../models/carModel");
router.get("/getallcars", async(req,res) => {
try {
const cars = await Car.find()
res.send(cars)
} catch (error) {
return res.status(400).json(error);
}
})
module.exports = router;
Finally, I export them into server.js which looks like this :
const express = require('express');
const app = express();
const port = process.env.port || 5000;
const dbConnect = require('./db');
app.use(express.json())
app.use('/api/cars/' , require('./routes/carsRoute'))
app.use('/api/users/', require('./routes/usersRoute'))
app.get('/', (req,res) => res.send('Hello World') )
app.listen(port, () => console.log(`Node Js Server Started on port ${port}`))
I do not think i missed any "/" or have any additional ones.