why my console.log(req.body) give: {} in nodejs - node.js

I want to update a post in my bdd with the new value. When i click for validate i have an empty req.body!
exports.updatePost = (req, res, next) => {
Post.update(
{
message: req.body.message,
},
{ where: { id: req.params.id } }
)
.then(() => res.status(200).json({ message: "post modifié" }))
.catch((error) => res.status(500).json({ error }));
console.log(req.body)
console.log(req.params.id)
};
As you can see i console log my req.body for check, my req.paramas.id give me the right thing. Since i have this problem i decided to check my post route and my app.js but i didn't see anything.
my route is like this:
const express = require("express");
const router = express.Router();
const postCtrl = require("../controllers/post");
const auth = require("../middleware/auth");
const multer = require("../middleware/multer-configs");
//DIFFERENTE ROUTES POUR LES POSTS, COMPRENNANTS LES DIFFERENTS MIDDLEWARE UTILES ET D'AUTHENTIFICATION
router.get("/", auth, postCtrl.getAllPost);
router.post("/", auth, multer, postCtrl.createPost);
router.delete("/:id", auth, postCtrl.deletePost);
router.put("/:id", auth, postCtrl.updatePost);
router.get("/:id", auth, postCtrl.getPostByUserId);
module.exports = router;
and my app.js is like this:
const express = require("express");
require("dotenv").config();
const helmet = require("helmet");
const cors = require("cors");
const db = require("./models");
const path = require("path");
const bodyParser = require("body-parser");
const userRoutes = require("./routes/user");
const postRoutes = require("./routes/post");
const likeRoutes = require("./routes/like");
const commentRoutes = require("./routes/comment");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//MODULE C.O.R.S
app.use(cors());
app.use(express.urlencoded({ extended: true }));
// POST
app.use("/api/post", postRoutes);
I don't really understand why my backend can't see the back or don't give me the result of my body.
my client side is like this actually:
const updatePost = () => {
if (textEdit) {
const data = new FormData();
data.append("message", textEdit);
axios.put(`http://localhost:5000/api/post/${id}`, data, {
headers: {
Authorization: `Bearer ${sessionStorage.getItem("authToken")}`,
},
})
.then((res) => {
console.log(res);
console.log(id)
console.log(message)
console.log(textEdit)
})
}
}

Related

Possible to pass a parameter into Express' app.use()

I have my Node/Express server running. I have the main server.js file where most of the code is for the server. Now I want to separate out the routes into a separate file. I have done this before using app.use(routes). But the problem is, I want to pass a string in for one of the routes to use.
Here is my server.js code:
// other imports
import routes from './routes.js';
const app = express();
...
const port = Number.parseInt(process.env.PORT, 10) || 3001;
const serverType = process.env.NODE_ENV === 'production' ? 'Production' : 'Test';
const statusMsg = `${serverType} Node server for external facing web server on ${port}`;
// i want `routes` to have access to `statusMsg`
app.use(routes);
Then in routes.js:
import express from 'express';
const router = express.Router();
router.get('/', (req, res) => res.status(200).send(statusMsg);
export default router;
I use serverType and port elsewhere in server.js, else I would just move all that code to routes.js.
Update
Adding in updated routes.js as I understand it with suggestion from jonrsharpe.
import express from 'express';
const router = express.Router();
const createRoutes = (statusMsg) => {
router.get('/', (req, res) => res.status(200).send(statusMsg);
};
export default createRoutes;
You can separate the server logic, routes logic, and business logic (usually inside a separate file called a controller).
inside the server file try blow code:
const express = require('express');
const app = express();
const bodyParser = require('body-parser')
require('dotenv').config();
const connectDB = require('./config/config')
const cookieParser = require('cookie-parser')
const authRoutes = require('./routes/authRoutes')
const categoryRoutes = require('./routes/categoryRoutes')
const cors = require('cors');
connectDB();
app.use(bodyParser.json());
app.use(cookieParser());
app.use(cors());
//Route Mounting
app.use('/', authRoutes);
app.use('/', categoryRoutes);
app.listen(process.env.PORT, ()=>{
console.log(`Server is running on PORT: ${process.env.PORT}`)
})
Then create a separate file authRoute.js and do the following code
const express = require('express')
const { registerUser, loginUser, getAllUsers, logoutUser} = require('../controllers/authController')
const router = express.Router()
const {isAuthenticatedUser, isAuthorizedRoles} = require('../middleware/auth')
router.route('/user/new').post(registerUser);
router.route('/user/login').post(loginUser);
router.route('/users').get(getAllUsers);
router.route('/account/logout').get(logoutUser);
module.exports = router;
lastly to write the business logic create file authController.js and place the following code.
const User = require('../model/userSchema');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
require('dotenv').config();
exports.registerUser = async (req, re, next)=>{
let password = req.body.password;
password = await bcrypt.hash(password, 10);
const newUser = req.body;
newUser.password = password;
try {
const user = await User.create(newUser);
if(user){
res.json({
success:true,
user
});
}
} catch (error) {
console.log(error);
}
}
exports.loginUser = async function(req, res){
const email = req.body.email;
const password = req.body.password;
if(!email || !password){
return res.json({
success:false,
message:'Please provide the email & Password'
})
}
const user = await User.findOne({email:email});
if(!user){
return res.json({
success:false,
message:'user with this email not found in database'
})
}
const isPasswordMatch = await bcrypt.compare(password, user.password);
if(!isPasswordMatch){
return res.json({
success:false,
message:'Your password is wrong...'
})
}
const token = jwt.sign({ _id: user._id }, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXPIRY_TIME });
res.cookie('token', token, {httpOnly:true, expires:new Date(Date.now() + 60*60*1000 )}).json({
success:true,
message:'You are logged in! Enjoy',
})
}
exports.getAllUsers = async (req, res, next)=>{
res.json({
success:true,
data:[
{
"id":1,
"name":"Yasir",
"qual":"MCS",
"age":32
},
{
"id":2,
"name":"Tabish",
"qual":"BS",
"age":21
},
{
"id":3,
"name":"Ahmed",
"qual":"BSCS",
"age":32
},
{
"id":4,
"name":"Hassan",
"qual":"MCS",
"age":33
}
]
})
}
exports.logoutUser = async (req, res, next)=>{
res.cookie('token', null, {expires:new Date(Date.now())}).json({
success:true,
message:'You are loggedOut',
})
}
This is the way you can have separation of concerns.

express nodejs body is empty after post request

I have tried all out there but still the post request is giving me an empty. I checked in browser and also in postman the values are sent via the payload, but when getting via the router post, req.body is empty
main
const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
// var bodyParser = require("body-parser"); body parser also didnt work
const app = express();
// app.use(
// bodyParser.urlencoded({
// extended: true,
// })
// );
// app.use(bodyParser.json());
app.use(cors());
app.use(express.urlencoded({ extended: true })); // interchanged this below express.json didnt work
app.use(express.json());
const PORT = 3009;
// import routes
const router = require("./routes/route");
app.use("/api", router);
// connect mongo start
const uri =
"mongodb+srv://adminuser:password#cluster0.gtkdj.mongodb.net/mydb?retryWrites=true&w=majority";
const options = {
useNewUrlParser: true,
useUnifiedTopology: true,
};
mongoose.connect(uri, options);
const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", function () {
console.log("Mongo Connected");
});
app.listen(PORT, () => {
console.log("Port is connected at ", PORT);
});
model
const mongoose = require("mongoose");
const dataSchema = mongoose.Schema({
name: {
type: String,
},
});
const dataModel = mongoose.model("data", dataSchema);
module.exports = dataModel;
routes
const express = require("express");
const router = express.Router();
const dataModel = require("../model/schema");
router.post("/new_items", (req, res) => {
const data = new dataModel({
name: req.body.name,
});
console.log(data, req.body);
data
.save()
.then((item) => res.send(item))
.catch((err) => res.status(400).send(err));
});
console output { _id: 6022f0c0b3dd8f2sdc5302f9 } {}
The req body is empty. Please help me on this. Thanks
The codes were correct. But, the post request header was not present. After passing the header, it worked as intended.
await fetch("http://localhost:3009/api/new_items/", {
method: "POST",
headers: {
"Content-Type": "application/json", // this was missing
},
body: JSON.stringify(body),
})

express server returns 405 on routes in production

Im building an express instance for the first time and ive run into an issue where everything works locally, but when deployed sending a post request to the route responds:
Failed to load resource: the server responded with a status of 405
(Not Allowed)
Ive included the relevant code below:
server/index.js
const express = require('express');
const bodyParser = require('body-parser')
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
const routes = require('./routes')(express)
require('./db')
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(process.env.PORT || 8080);
app.use('/', routes);
routes/index.js
var mongoose = require("mongoose");
const randomId = require('random-id');
const Submissions = require('../api/Submissions')
// routes/index.js
module.exports = (express) => {
// Create express Router
var router = express.Router();
// add routes
router.route('/submission')
.post((req, res) => {
let newSubmission = new Submissions(req.body);
newSubmission._id = randomId(17, 'aA0');
// Save the new model instance, passing a callback
newSubmission.save(function(err,response) {
if (err) {
console.log(err)
} else {
res.setHeader('Content-Type', 'application/json');
res.json({'success':true})
}
// saved!
})
});
return router;
}
client.js
let submission = {
name: this.state.newSubmission.name.trim(),
body: this.state.newSubmission.body.trim(),
email: this.state.newSubmission.email.trim(),
};
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(submission),
};
fetch("/submission", requestOptions)
.then((response) =>
response.json().then((data) => ({
data: data,
status: response.status,
}))
)
.then((res) => {
if (!res.data.success) {
notifier.warning('Failed to submit');
} else {
notifier.success('Submission successful');
}
});

Using express session to share information across different routes

I am wondering if anyone could help me please.
I have a react app that contains dialogflow (google's chatbot platform). I would like to share information in a user route to a dialogflow fulfillmentRoute using express-session. Here is my main server.js file. In the server.js I have declared an express-session
server.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const path = require('path');
var cors = require('cors')
const users = require('./routes/api/users');
const db = require('./config/keys').mongoURI;
require('./models/Users');
const app = express();
const session = require('express-session')
// Body parser middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cors());
require('./routes/fulfillmentRoutes')(app);
app.use(session({secret: 'ssshhhhh'}));
// Connect to MongoDB
mongoose
.connect(db)
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
// Passport middleware
app.use(passport.initialize());
// Passport Config
require('./config/passport')(passport);
// Use Routes
app.use('/api/users', users);
// Server static assets if in production
if (process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static('client/build'));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on port ${port}`));
In the user.js route file, I then have this to save an email into a session variable;
user.js
router.post(
'/',
passport.authenticate('jwt', { session: false }),
(req, res) => {
sess = req.session;
var emails = req.user.email;
sess.emails;
res.json({ msg: 'Users Works' })
res.json({
id: req.user.id,
firstname: req.user.firstname,
lastname: req.user.lastname,
email: req.user.email,
week: req.user.week,
age: req.user.age
});
}
);
In my dialogflow fullfillment route file, I have the following;
fulfillmentRoutes.js
const {WebhookClient, Payload, Card} = require('dialogflow-fulfillment');
const express = require('express');
const chatbot = require('../chatbot/chatbot');
const mongoose = require('mongoose');
const passport = require('passport');
const keys = require('../config/keys');
const sourceFile = require('./api/users.js');
const User = require('../models/User');
module.exports = app => {
var router = express.Router();
app.post('/api/df_text_query', async (req, res) => {
let responses = await chatbot.textQuery(req.body.text, req.body.userID, req.body.parameters);
res.send(responses[0].queryResult);
});
app.post('/api/df_event_query', async (req, res) => {
let responses = await chatbot.eventQuery(req.body.event, req.body.userID, req.body.parameters);
res.send(responses[0].queryResult);
});
app.post('/', async (req, res) => {
const agent = new WebhookClient({ request: req, response: res });
async function welcome(agent) {
let user = await User.findOne({'email': sess.emails});
if (user !== null ) {
responseText = `${sess.emails}`;
}
agent.add(responseText);
}
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
agent.handleRequest(intentMap);
});
return router;
}
In the welcome async function in fulfillment.js route, I use sess.emails that was declared in the user.js routes file. However the variable comes back undefined. Any guidance or help will be appreciated please.
Thanks
In your user.js, sess.emails; is not being assigned any variable.
Can you try replacing it sess.emails = emails; and check if the emails field is undefined?

Mongo/express cannot load route (Unexpected '<' in postman)

Been trying to get user user object by id from parameters, using User.findById and cannot access this route.
Postman response: Cannot GET /users/get/ with status 404 (not found) which is wierd.
Postman JSON response:
Unexpected '<'
Been using express-promise-router but also tried with default express.Router();
Here is my code:
routes/users.js
const express = require('express');
const router = require('express-promise-router')();
const passport = require('passport');
const router1 = express.Router();
require('../passport');
const { validateBody, schemas } = require('../helpers/routeHelpers');
const UsersController = require('../controllers/users');
const passportSignIn = passport.authenticate('local', { session: false });
const passportJWT = passport.authenticate('jwt', { session: false });
router.route('/signup')
.post(validateBody(schemas.authSchema), UsersController.signUp);
router.route('/signin')
.post(validateBody(schemas.authSchema), passportSignIn, UsersController.signIn);
router.route('/get/:id')
.get(UsersController.getUser);
router.route('/secret')
.get(passportJWT, UsersController.secret);
controllers/users
module.exports = router;
const JWT = require('jsonwebtoken');
const User = require('../models/user');
const { JWT_SECRET } = require('../configuration');
const signToken = (user) => {
return JWT.sign({
iss: 'CodeWorkr',
sub: user.id,
iat: new Date().getTime(), // current time
exp: new Date().setDate(new Date().getDate() + 1) // current time + 1 day ahead
}, JWT_SECRET);
};
module.exports = {
signUp: async (req, res) => {
const { email, password } = req.value.body;
// Check if there is a user with the same email
const foundUser = await User.findOne({ 'local.email': email });
if (foundUser) {
return res.status(403).json({ error: 'Email is already in use' });
}
// Create a new user
const newUser = new User({
method: 'local',
local: {
email: email,
password: password
}
});
await newUser.save();
// Generate the token
const token = signToken(newUser);
// Respond with token
return res.status(200).json({ token });
},
signIn: async (req, res) => {
// Generate token
const token = signToken(req.user);
res.status(200).json({ token });
},
getUser: async (req, res) => {
User.findById(req.params.id)
.then((user) => {
res.status(200).json({ user });
console.log('test');
});
},
secret: async (req, res) => {
console.log('I managed to get here!');
res.json({ secret: 'resource' });
}
};
server.js
const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const passport = require('passport');
const db = require('./configuration/config').mongoURI;
const dbTest = require('./configuration/config').mongoURITest;
mongoose.Promise = global.Promise;
if (process.env.NODE_ENV === 'test') {
mongoose.connect(dbTest, { useMongoClient: true });
} else {
mongoose.connect(db, { useMongoClient: true });
}
const app = express();
app.use(cors());
app.use(passport.initialize());
app.use(passport.session());
// Middlewares moved morgan into if for clear tests
if (!process.env.NODE_ENV === 'test') {
app.use(morgan('dev'));
}
app.use(bodyParser.json());
// Routes
app.use('/users', require('./routes/users'));
// Start the server
const port = process.env.PORT || 3001;
app.listen(port);
console.log(`Server listening at ${port}`);
Other post routes works fine,

Resources