Empty body with express and nodejs - node.js

I am trying to insert a new record by express and node js using mongoose.
My config is my app.js:
import express from 'express';
import morgan from 'morgan';
import cors from 'cors';
import path from 'path';
const app = express();
// Conexión base de datos
const mongoose = require('mongoose');
const uri = 'mongodb://localhost:27017/marcosgarciatfg';
const options = {useNewUrlParser: true, useCreateIndex: true};
// Or using promises
mongoose.connect(uri, options).then(
/** ready to use. The `mongoose.connect()` promise resolves to mongoose instance. */
() => {
console.log('Conectado a DB');
},
/** handle initial connection error */
err => {
console.log(err);
}
);
app.use('/api', require('./routes/nota.js'));
//Middleware
app.use(morgan('tiny'));
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
//app.use(express.static(path.join(__dirname, 'public')));rs
// Rutas
app.get('/', (req, res) => {
res.send('Hello Wooooorld!');
});
And this my nota.js on routes:
import express from 'express';
const router = express.Router();
// importar el modelo nota
import Nota from '../models/nota';
// Agregar una nota
router.post('/nueva-nota', async(req, res) => {
const body = req.body;
try {
console.log('body: ' + body);
const notaDB = await Nota.create(body);
res.status(200).json(notaDB);
} catch (error) {
return res.status(500).json({
mensaje: 'Ocurrio un error',
error
});
}
});
This returns always 200:OK on Postman with empty response and in the console log the body is always undefined. What do I do wrong?

You need to apply express.json() middleware before using routes.
//Middleware
app.use(morgan('tiny'));
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/api', require('./routes/nota.js'));

Related

why req.body is empty and req.files undefined

I'm using node and express and I'm trying to upload some files and some information with a form. The issue is that when I try to acces to anything in the form from backend it is undefined or empty. When I use req.body it's empty and when I try to use req.files they are undefined so I don't know what to do. This is the code:
routerProgress.post("/home/upload-progress", (req, res) => {
const user_id = req.user.id;
console.log(req.body);
const weight = req.body.weight;
const front = req.files.front;
const from_side = req.files.from_side;
const backwards = req.files.backwards;
let front_id = `${v4()}-${front.file.name}`;
let from_side_id = `${v4()}-${from_side.file.name}`;
let backwards_id = `${v4()}-${backwards.file.name}`;
const date = dateFormat(result.request_date, "yyyy-mm-dd");
from.mv('../../uploads/images', front_id, (req, res) => {
if (err) console.log(err);
else console.log("File Uploaded");
})
from_side.mv('../../uploads/images', from_side_id, (req, res) => {
if (err) console.log(err);
else console.log("File Uploaded");
})
backwards.mv('../../uploads/images', backwards_id, (req, res) => {
if (err) console.log(err);
else console.log("File Uploaded");
})
const newProgress = new Progress ({
user_id,
weight,
front_id,
from_side_id,
backwards_id,
date
})
res.redirect("/home");
});
The console.log is only {} and req.files.name_defined_in_form are undefined.
Here is my app.js
import express from 'express';
const app = express();
import path from 'path';
import sequelize from './db/db.js';
import { fileURLToPath } from 'url';
import flash from 'connect-flash';
import session from 'express-session';
import passport from 'passport';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// SERVER CONFIGURATION
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Listening at ${PORT}`);
sequelize.sync({ force: false })
.then(() => console.log('Database Connected!'))
.catch(err => console.log(err));
});
// VIEW SETTINGS
app.use(express.static(__dirname + "/public"));
app.set("view engine", "pug");
// app.engine('html', require('ejs').renderFile);
app.set('views', path.join(__dirname, "/public/views"));
// BODYPARSER
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
// EXPRESS SESSION
app.use(session({
secret: 'GymApp',
resave: true,
saveUninitialized: true
}));
// CONNECT FLASH
app.use(flash());
// PASSPORT MIDDLEWARE
import passportConfig from './config/passport.js';
passportConfig(passport);
app.use(passport.initialize());
app.use(passport.session());
// GLOBAL VAR
app.use((req, res, next) => {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
});
// ROUTES
import { routerIndex } from './routes/index.js';
import { routerProgress } from './routes/app/progress.js';
import { routerAuthentication } from './routes/authentication.js';
import { routerHome } from './routes/app/home.js'
app.use(routerIndex);
app.use(routerProgress);
app.use(routerAuthentication);
app.use(routerHome);
And here is the form done with pug:
form(class="form add-form space-down" method="POST" enctype="multipart/form-data")
div.title
h1 UPLOAD NEW PROGRESS
div.form-group
label(for="weight") Weight:
input(type="number" name="weight" class="form-control" placeholder="Enter your weight")
div.form-group
label(for="front") Upload a front photo
input(type="file" name="front")
div.form-group
label(for="from_side") Upload a from side photo
input(type="file" name="from_side")
div.form-group
label(for="backwards") Upload a backwards photo
input(type="file" name="backwards")
div.button-container
button(type="submit" class="btn btn-primary btn-color space") Upload
If anyone know what I should do to solve this issue I would be very grateful with him.
In order to access the req.files object, you need to add a specific middleware named express-fileupload that allows this functionality.
Simply run npm i express-fileupload, and then add it to your app.js, like so:
const fileUpload = require('express-fileupload');
app.use(fileUpload());
In your specific app.js, you could add it near your other middleware, such as:
import express from 'express';
const app = express();
import path from 'path';
import sequelize from './db/db.js';
import { fileURLToPath } from 'url';
import flash from 'connect-flash';
import session from 'express-session';
import passport from 'passport';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// SERVER CONFIGURATION
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Listening at ${PORT}`);
sequelize.sync({ force: false })
.then(() => console.log('Database Connected!'))
.catch(err => console.log(err));
});
// FILE UPLOAD
const fileUpload = require('express-fileupload');
app.use(fileUpload());
// VIEW SETTINGS
app.use(express.static(__dirname + "/public"));
app.set("view engine", "pug");
// app.engine('html', require('ejs').renderFile);
app.set('views', path.join(__dirname, "/public/views"));
// BODYPARSER
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
// EXPRESS SESSION
app.use(session({
secret: 'GymApp',
resave: true,
saveUninitialized: true
}));
// CONNECT FLASH
app.use(flash());
// PASSPORT MIDDLEWARE
import passportConfig from './config/passport.js';
passportConfig(passport);
app.use(passport.initialize());
app.use(passport.session());
// GLOBAL VAR
app.use((req, res, next) => {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
});
// ROUTES
import { routerIndex } from './routes/index.js';
import { routerProgress } from './routes/app/progress.js';
import { routerAuthentication } from './routes/authentication.js';
import { routerHome } from './routes/app/home.js'
app.use(routerIndex);
app.use(routerProgress);
app.use(routerAuthentication);
app.use(routerHome);
After installing and implementing the middleware via app.use(), the req.files object should now be accessible, given you are passing the files from your form properly.

Postman keeps loading on sending POST request to an express route

I created a route and controller for my sign up.
Here's my route:
const express = require("express");
const router = express.Router();
const { signup } = require("../../controllers/auth");
router.post("/signup", signup);
module.exports = router;
And here's my controller:
exports.signup = () => (req, res) => {
const { name, email, password } = req.body;
res.json({
user: { name, email, password },
});
};
Inside my server.js file I register both:
const express = require("express");
const morgan = require("morgan");
const cookieParser = require("cookie-parser");
const cors = require("cors");
const mongoose = require("mongoose");
require("dotenv").config();
// routes
const blogRoutes = require("./routes/blog");
const authRoutes = require("./routes/auth");
// app
const app = express();
// db
mongoose
.connect(process.env.DATABASE, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log("DB connected!"));
// middlewares
app.use(morgan("dev"));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(cookieParser());
// cors
if (process.env.NODE_ENV == "development") {
app.use(cors({ origin: `${process.env.CLIENT_URL}` }));
}
// routes middleware
app.use("/api", blogRoutes);
app.use("/api", authRoutes);
// port
const port = process.env.PORT || 8000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Now on my POSTMAN, I tried to put the data using POST http://localhost:8000/api/signup with the header and raw setup right.
{
"name": "SyRyan",
"email": "syryan#gmail.com",
"password": "brace1010"
}
The database is connected but the postman takes forever to load the json request back. Am I making any mistakes here? Please help!
I think that the problem is that signup is a function that returns a function, but it should be just a function that receives req & res as parameters:
exports.signup = (req, res) => {
const { name, email, password } = req.body;
res.json({
user: { name, email, password },
});
};

My Local Host is keep loading although my mongodb server is connected amd running

I am following the brad Traversy Nodejs Tutorial my server is connected and started also my Mongodb connection is running but localhost keep loading and not responding.
I have checked my URL for mongo connection also the password and username all are correct. I have also allow network access from all sources.
This was perfectly working before but now this keeps loading and loading
my db.js
const mongoose = require("mongoose")
const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useFindAndModify: false,
useUnifiedTopology: true
})
console.log(`MongoDB connected ${conn.connection.host}`)
} catch (err) {
console.error(err)
process.exit(1)
}
}
module.exports = connectDB
my app.js
const express = require("express")
const path = require("path")
const dotenv = require('dotenv')
const morgan = require('morgan')
const exphbs = require('express-handlebars')
const passport = require('passport')
const connectDB = require('./config/db')
const routes = require('./routes/index')
const session = require("express-session")
const MongoDBStore = require('connect-mongodb-session')(session);
const mongoose = require('mongoose')
const methodOverride = require('method-override')
//locad config
dotenv.config({ path: './config/config.env' })
connectDB()
//passport config
require('./config/passport')(passport)
const app = express()
const PORT = process.env.PORT || 5000
//body parser
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
//method override
// Method override
app.use(
methodOverride(function (req, res) {
if (req.body && typeof req.body === 'object' && '_method' in req.body) {
// look in urlencoded POST bodies and delete it
let method = req.body._method
delete req.body._method
return method
}
})
)
//logging
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'))
}
//handlebars helpers
const { formatDate, truncate, stripTags, select } = require('./helpers/hbs')
//Hnadlebars
app.engine('.hbs', exphbs({ helpers: { formatDate, truncate, stripTags, select }, defaultLayout: 'main', extname: '.hbs' }));
app.set('view engine', '.hbs');
//sessions
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUnitialized: false,
store: new MongoDBStore({
mongooseConnection: mongoose.connection
})
//cookie: { secure: true }
}))
//set passport middleware
app.use(passport.initialize())
app.use(passport.session())
//set global variable
app.use(function (req, res, next) {
res.locals.user = req.user || null
})
//static folder
app.use('/', express.static(path.join(__dirname, 'public')))
//Routes
app.use('/', routes);
app.use('/auth', require('./routes/auth'));
app.use('/stories', require('./routes/stories'));
//listen
app.listen(PORT, console.log(
`server is running in ${process.env.NODE_ENV} mode on port ${PORT}`
))
my ./routes/index.js
const express = require('express')
const router = express.Router()
const { ensureAuth, ensureGuest } = require('../middleware/auth')
const Story = require('../models/story')
//#desc Login/Landing Page
//#route GET/
router.get('/', ensureGuest, (req, res, next) => {
res.render("login", {
layout: "login"
})
})
//#desc Login/Landing Page
//#route GET/
router.get('/dashboard', ensureAuth, async (req, res, next) => {
console.log(req.user)
try {
const stories = await Story.find({ user: req.user._id }).lean() //plain Js object
res.render("dashboard", {
name: req.user.firstName,
stories
})
} catch (error) {
console.log('Stories error', error)
res.render('error/500')
}
})
module.exports = router
my browser
I have found if you're using middlewares then must call next function at the end this was the reason my page wasn't loading
The error was at //set global variable middleware

POST route indicating 404 error (EXPRESS)

Getting a 404 error on my POST route, here is what I have done in my auth.js (routes) file:
const express = require('express');
const router = express.Router();
const connection = require('../../helpers/db.js');
const bodyParser = require("body-parser");
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({
extended: true
}));
//create a new user
router.post('/signup', function (req, res) {
const insert = `INSERT INTO users ( email, password, name, lastname) values ('${req.body.email}', '${req.body.password}','${req.body.name}', '${req.body.lastname}' )`
connection.query(insert, function (err, result) {
if(err) {
console.log('mysql error', error);
res.status(500);
res.send(error);
} else {
console.log('a new user was added!');
res.send('Congrats, new user!');
}
})
});
module.exports = router;
Here is my app.js file:
const http = require("http");
const path = require("path");
const express = require("express");
const bodyParser = require("body-parser");
const morgan = require("morgan");
const app = express();
const authRouter = require("./routes/auth/auth");
// Configuring the app
app.use(morgan("dev"));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(__dirname + "/public"));
app.use("/signup", authRouter);
//starting node server
const server = app.listen(process.env.PORT || 3001, function(err) {
if(err) throw err;
console.log("Listening on port " + server.address().port);
});
If I change my route into a GET, it works fine, but as soon as I do a POST route it would keep telling me on postman there is a 404 error, been trying many things but im now stuck! Im a beginner here :)
I think you added a prefix to your route so the route is /signup/signup
Try to change this
app.use("/signup", authRouter);
To this
app.use(authRouter);

express-validator error -> TypeError: req.checkBody is not a function

I am using express-validator package to validate requested data.
According to these answer I also did change the order or package declaration and initialization
below is my server.js file
const express = require("express");
const session = require("express-session");
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo')(session);
const path = require('path');
const cookieParser = require("cookie-parser");
const bodyParser = require("body-parser");
const passport = require('passport');
const promisify = require('es6-promisify');
const expressValidator = require('express-validator');
const expressJwt = require("express-jwt");
const error_staus = 404;
const morgan = require('morgan');
const logger = require('./helper/logger');
const routes = require('./routes/index');
let server = "";
const bugsnag = require('bugsnag');
// import our configurations from config/tester.js file
const config = require("./config/tester").get(process.env.NODE_ENV);
require('./helper/passport');
require("./helper/translator");
// create our Express app
const app = express();
// view engine setup
app.set("views", `${__dirname}/views`);
app.set("view engine", "ejs");
// serves up static files from the public folder. Anything in app/ will just be served up as the file it is
app.use(express.static(path.join(__dirname, 'app')));
// Takes the raw requests and turns them into usable properties on req.body
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Exposes a bunch of methods for validating data. Used heavily on userController.validateRegister
app.use(expressValidator());
// Sessions allow us to store data on visitors from request to request
app.use(session({
secret: '123456',
key: '99785',
resave: false,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection })
}));
app.use(session({
"secret": 'secret12345',
"resave": false,
"saveUninitialized": true
}));
// Passport JS is what we use to handle our logins
app.use(passport.initialize());
app.use(passport.session());
// promisify some callback based APIs
app.use((req, res, next) => {
req.login = promisify(req.login, req);
next();
});
// begin logger
app.use(morgan('dev', {
skip: function (req, res) {
return res.statusCode < 400
}, stream: process.stderr
}));
app.use(morgan('dev', {
skip: function (req, res) {
return res.statusCode >= 400
}, stream: process.stdout
}));
app.use('/', routes);
app.use(function(req, res, next){
logger.error('404 page requested');
res.sendStatus(error_staus);
});
// done! we export it so we can start the site in start.js
module.exports = app;
This is the userController.js
const mongoose = require('mongoose');
const User = mongoose.model('User');
const promisify = require('es6-promisify');
exports.loginForm = (req, res) => {
res.render('login', { title: 'Login' });
};
exports.registerForm = (req, res) => {
res.render('register', { title: 'Register' });
};
exports.validateRegister = (req, res, next) => {
req.sanitizeBody('name');
req.checkBody('name', 'You must supply a name!').notEmpty();
req.checkBody('email', 'That Email is not valid!').isEmail();
req.sanitizeBody('email').normalizeEmail({
gmail_remove_dots: false,
remove_extension: false,
gmail_remove_subaddress: false
});
req.checkBody('password', 'Password Cannot be Blank!').notEmpty();
req.checkBody('password-confirm', 'Confirmed Password cannot be blank!').notEmpty();
req.checkBody('password-confirm', 'Oops! Your passwords do not match').equals(req.body.password);
const errors = req.validationErrors();
if (errors) {
req.flash('error', errors.map(err => err.msg));
res.render('register', { title: 'Register', body: req.body, flashes: req.flash() });
return; // stop the fn from running
}
next(); // there were no errors!
};
Note : I am using express-validator version 3.1.2
When I check request object, in that object there is all methods of express-validator too.
But try to use that method I am getting req.checkBody is not a function error.
Can anybody help with these issue ?

Resources