Express body-parser request.body returning undefined - node.js

when i run this app and submit the form 'console.log(request.body)' returning undefined. i am a beginner in node js . can anyone please explain what i am doing wrong?
this is the registration form
register.jade
doctype html
html
head
title.
Fonebook
link(rel='stylesheet', href='/assets/bootstrap/css/bootstrap.min.css')
script(src='https://code.jquery.com/jquery-2.2.0.min.js')
script(src='/assets/bootstrap/js/bootstrap.min.js')
body
div.container
h3.
The Fonebook
form(method="POST",class="center",id="regForm",action='/doReg',enctype="multipart/form-data")
div.panel.panel-info
div.panel-heading.
Registration
div.panel-body
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Profile Picture:
input(type='file',name='proPic')
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Email:
input.form-control(id="email", type="email", name="email", placeholder="Enter email ")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Name:
input.form-control(id="name", type="text", name="name", placeholder="Enter name ")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
label.
Password:
input.form-control(id="password", type="password", name="password")
div.col-md-offset-3.col-md-6.col-md-offset-3.form-group
a(href='login').
Already have an account?
div.panel-footer
button.btn.btn-info(type="submit").
Register
here is my app.js file
var express = require('express');
var app = express();
var mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1/test');
var uploadDir = __dirname + '/uploads';
var fs = require('fs');
var multer = require('multer');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
var conn = mongoose.connection;
app.set('views', './views');
app.set('view engine', 'jade');
app.use('/assets', express.static(__dirname + '/public'));
var port = process.env.PORT || 3000;
app.all('/', function (req, res) {
res.render('login');
})
app.all('/register', function (req, res) {
res.render('register');
})
app.all('/login', function (req, res) {
res.render('login');
})
var storage = multer.diskStorage({
destination: function (request, file, callback) {
callback(null, uploadDir);
},
filename: function (request, file, callback) {
//console.log(file);
callback(null, Date.now() + '.jpg');
}
});
var upload = multer({storage: storage}).single('proPic');
app.all('/doReg', function (request, response) {
upload(request, response, function (err) {
if (err) {
console.log(err);
return;
}
//console.log(request.file);
response.end('Your File Uploaded');
})
console.log(request.body);
});
app.listen(port);

body-parser does not support multipart forms.
From their README
This does not handle multipart bodies, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules:
busboy and connect-busboy
multiparty and connect-multiparty
formidable
multer
Seeing as you're already using multer you can access your fields this way:
app.all('/doReg', upload, function (request, response) {
console.log(request.body);
});

Related

Multer nodejs - req.file is undefined

I am creating an app using Node, Express and ejs and multer for uploading images. Every time I submit the form, req.file is undefined. I've spent the entire day troubleshooting but can't figure out what I'm doing wrong.
HTML
<form action="/post" id="formPost" method="post" enctype="multipart/form-data">
<input class="img-file" type="file" name="image" required>
<input class="submit" type="submit" value="Post" />
</form>
app.js
const path = require('path');
const express = require('express');
const morgan = require('morgan');
const bodyParser = require("body-parser");
const multer = require('multer');
const app = express();
app.use(express.static(path.join(__dirname, 'public')))
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname,'resources/views'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./image");
},
filename: function (req, file, cb) {
console.log(req.file);
cb(null, Date.now() + "-" + file.fieldname + ".png");
},
});
const upload = multer({ storage: storage });
app.post("/post", upload.single("image"), (req, res) => {
console.log(req.file);
});
app.get("/post", (req, res) => {
res.render("post");
});
app.listen(, () => {
console.log(`Example app listening at http://localhost:3000/login`);
});
You have few little bugs: first you forgot to add port and instead of login it should be post then we hit the correct address immediately, avoiding error Cannot GET /login
app.listen(3000, () => {
console.log(`Example app listening at http://localhost:3000/post`);
});
Project Folder & File structure:
app.js I added simple an error handler to the:
app.post("/post", upload.single("image"), (req, res, next) => {}
const path = require("path");
const express = require("express");
const morgan = require("morgan");
const bodyParser = require("body-parser");
const multer = require("multer");
const app = express();
app.use(express.static(path.join(__dirname, "public")));
app.set("view engine", "ejs");
app.set("views", path.join(__dirname, "resources/views"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./image");
},
filename: function (req, file, cb) {
console.log(req.file);
cb(null, Date.now() + "-" + file.fieldname + ".png");
},
});
const upload = multer({ storage: storage });
// app.post("/post", upload.single("image"), (req, res) => {
// console.log(req.file);
// });
app.post("/post", upload.single("image"), (req, res, next) => {
const file = req.file;
if (!file) {
const error = new Error("Please upload a file");
error.httpStatusCode = 400;
return next(error);
}
res.send(file);
console.log("Success", req.file);
});
app.get("/post", (req, res) => {
res.render("post");
});
app.listen(3000, () => {
console.log(`Example app listening at http://localhost:3000/post`);
});
post.ejs
<form action="/post" id="formPost" method="post" enctype="multipart/form-data">
<input class="img-file" type="file" name="image" required />
<input class="submit" type="submit" value="Upload File" />
</form>
output:
after selecting the file and pressing upload file:
VSCode output:
Works like a charm ;-)

How can I prevent express-ejs-layouts for wrapping my other page?

I'm finding a page layout for node.js like laravel php have their Template for layout and it is perfect. I want to achieve it here in node.js and finally found this express-ejs-layouts but there is a problem in it that I cant see in their documentation the layout will wrap all of my pages specially my signin and signup page which have a different header and footer. How can we prevent express-ejs-layouts from wrapping my other page?
const express = require('express');
const router = express.Router();
const path = require('path');
const multer = require('multer');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const app = express();
const server = require('http').createServer(app);
const expressLayouts = require('express-ejs-layouts');
// Set Database Connection
const connection=mysql.createConnection({
host:'localhost',
user:'root',
password:'',
database:'project_101'
});
connection.connect(function(error){
if(!!error) console.log(error);
else console.log('Database Connected!');
});
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.static('assets'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(bodyParser.urlencoded({extended: true}));
app.use(expressLayouts);
app.get('/',(req, res) => {
let sql = "SELECT * FROM uploads";
let query = connection.query(sql, (err, rows) => {
if(err) throw err;
res.render('index');
});
});
app.get('/signup', (req, res) => {
res.render('signup');
});
app.get('/signin', (req, res) => {
res.render('signin');
});
app.get('/unknown-user', (req, res) => {
res.render('unknown-user');
});
app.get('/profile', (req, res) => {
res.render('profile');
});
const port = process.env.PORT || 3000;
// Server Listening
server.listen(port, function () {
console.log('Server successfully running at: -',port);
});
Finally got the solution for the problem express-ejs-layouts
const express = require('express');
const expressLayouts = require('express-ejs-layouts');
app.use(expressLayouts);
You just need to declare your page as a layout and set it to false.
app.set("layout signin", false);
and render the page together with the layout.
app.get('/signin', (req, res) => {
res.render('signin', { layout: 'signin' });
});
ez fix ⚡️
You can bypass the template by sending the file back.
res.sendFile(path, options, fn);
options and fn are optional.

Why is my NodeJS App not working as it should?

I don't understand what is my mistake but the app.Method are not really working.
server.js :
//express :
var express = require('express')
var app = express()
var bodyParser = require('body-parser')
//middleware :
app.use(express.json);
app.use(bodyParser.urlencoded({ extended:false }))
//templating engine :
var ejs = require('ejs');
app.set('view engine', ejs);
//public directory :
app.use(express.static(__dirname + '/public'));
//pages:
app.get('/', function (req, res) {
console.log("Hello")
res.render('pages/index')
})
app.get('/post/new', function (req, res) {
res.render('pages/post-new')
})
app.post('post/new', function (err, req) {
console.log(req.body)
})
//listening
app.listen(8080, function (err, res) {
if (err) throw err;
else console.log(`Listening on 8080`)
});
I have my directory something like this:
node-modules
public
views
--pages
----index.ejs
----post-new.ejs
--partials
package-lock.json
package.json
server.js
I don't really understand why is it not working. I have tried adding console.log(req) in app.gets but they don't really log anything. And sorry for the dumb question.
EDIT: Answer is It is app.use(express.json()) NOT app.use(express.json)

Nodejs shows Error "Cannot GET /test"

I am trying to retrieve output on other url / directory in nodejs but it's Display Error ("Cannot GET /test").
Please Suggest me what i have to do to get my output on ("http://localhost:8080/test").
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer();
var session = require('express-session');
var cookieParser = require('cookie-parser');
app.set('view engine', 'pug');
app.set('views','./views');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(upload.array());
app.use(cookieParser());
app.use(session({secret: "Your secret key"}));
var Users = [];
app.get('/', function(req, res){
res.render('signup');
});
app.post('/signup', function(req, res){
if(!req.body.id || !req.body.password){
res.status("400");
res.send("Invalid details!");
} else {
Users.filter(function(user){
if(user.id === req.body.id){
res.render('signup', {
message: "User Already Exists! Login or choose another user id"});
}
});
var newUser = {id: req.body.id, password: req.body.password};
Users.push(newUser);
req.session.user = newUser;
res.redirect('/test');
}
});
app.listen(8080);
OutPut : Cannot GET /test
You did not specify a route for /test. You should have
app.get('/test', function(req, res, next){
res.render('test'); // This should have a view
});
Here i writing sample. create views folder in root folder and add one test.pub file to views then just run
Note:dont forget to install pug and express
var express = require('express')
var app = express()
app.set('view engine', 'pug');
app.set('views','./views');
// here am directly sending response without using view engine
app.get('/', function (req, res) {
res.send('hello world')
})
// here am sending response with using view engine
app.get('/test', function(req, res){
res.render('test');
});
app.listen(8000,function(){
console.log(" Server is running on port 8000");
});

Formidable doesnt form.parse() when uploading a file in Nodejs

When i send a file to /upload, from the terminal I can see that the code is blocked at form.parse(req... On the Internet I read that this is because I use bodyParser(), and people suggested to do this:
delete express.bodyParser.parse['multipart/form-data'];
however when I do that my code crashes since parse is null.
Anyone has any idea on how to get file upload working only in /upload and possibly with formidable?
Thanks.
This is my app.js:
'use strict';
var express = require("express");
var async = require("async");
var http = require('http');
var url = require("url");
var qs = require("querystring");
var fs = require("fs");
var formidable = require("formidable");
var mime = require("mime");
var app = module.exports = express();
app.configure(function () {
app.set("views", __dirname + "/views");
app.set("view engine", "ejs");
app.engine("html", ejs.renderFile);
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser("abc"));
app.use(express.static(__dirname + "/static"));
app.use(app.router);
app.use(express.limit('5mb'));
});
app.post('/upload', storage.upload);
This is my code storage.js:
'use strict';
var async = require('async');
var formidable = require('formidable');
var fs = require('fs');
var util = require('util');
var api = require('./common');
exports.upload = function (req, res) {
console.log("I am here");
var form = new formidable.IncomingForm(),
files = [],
fields = [];
form.uploadDir = "./uploads";
form
.on('field', function (field, value) {
console.log(field, value);
fields.push([field, value]);
})
.on('error', function (err) {
res.writeHead(200, {'content-type': 'text/plain'});
res.end('error:\n\n'+util.inspect(err));
})
.on('file', function (field, file) {
console.log(field, file);
files.push([field, file]);
})
.on('aborted', function (err) {
console.log("user aborted upload");
})
.on('end', function () {
console.log('-> upload done');
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received fields:\n\n '+util.inspect(fields));
res.write('\n\n');
res.end('received files:\n\n '+util.inspect(files));
});
form.parse(req);
};
If you want to use formidable then, remove app.use(express.bodyParser());
& add app.use(express.json());app.use(express.urlencoded());
Connect 3.0
This solution worked for me, it might be helpful for other dev.
Have you seen the example on github: https://github.com/visionmedia/express/blob/master/examples/multipart/index.js
I've modified it to run on Express 3.x and it seems to work smoothly:
var express = require('express');
var fs = require('fs');
var app = express();
var format = require('util').format;
// bodyParser in connect 2.x uses node-formidable to parse
// the multipart form data.
app.use(express.bodyParser())
app.get('/', function(req, res){
res.send('<form method="post" enctype="multipart/form-data">'
+ '<p>Title: <input type="text" name="title" /></p>'
+ '<p>Image: <input type="file" name="image" /></p>'
+ '<p><input type="submit" value="Upload" /></p>'
+ '</form>');
});
app.post('/', function(req, res, next){
// the uploaded file can be found as `req.files.image` and the
// title field as `req.body.title`
res.send(format('\nuploaded %s (%d Kb) to %s as %s'
, req.files.image.name
, req.files.image.size / 1024 | 0
, req.files.image.path
, req.body.title));
});
if (!module.parent) {
app.listen(3000);
console.log('Express started on port 3000');
}

Resources