Reputation: 1185
I am trying to console.log a input from a form. However, the body-parser is showing 'undefined' for the input I am trying to print on my terminal. I am not sure what I did incorrect. Please advise what I did wrong. Thank You.
HTML form
<html>
<header>
<link rel="stylesheet" type="text/css" href="css/form.css">
</header>
<body>
<form id="form" class="topBefore" action="/form" method="post" enctype="multipart/form-data">
<input id="name" name="name" type="text" placeholder="NAME">
<input id="email" name="email" type="text" placeholder="E-MAIL">
<textarea id="message" name ="message" type="text" placeholder="MESSAGE"></textarea>
<input type="file" name="upload" multiple>
<input id="submit" type="submit" value="GO!">
</form>
</body>
</html>
App.js
// port and modules
var port = 3000;
var express = require('express');
var http = require('http');
var path = require('path');
var formidable = require('formidable');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var fs = require('fs');
var app = express();
// static resource folder (public)
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.get('/form', function(req, res){
res.sendFile(__dirname + "/public/form.html");
});
app.post('/form', function(req, res)
{ //get form input
var name = req.body.name;
var email = req.body.email;
var message = req.body.message;
console.log(req.body.name);
//upload file and save to directory
var form = new formidable.IncomingForm();
form.parse(req);
//set upload path
form.on('fileBegin', function (name, file){
file.path = __dirname + '/public/icons/' + file.name;
console.log(file.path);
});
//upload process
form.on('file', function (name, file){
console.log('Uploaded ' + file.name);
});
// redirect to home page after form submission
res.redirect('/');
});
// connect to server and listen port
// index.html will be home page
http.createServer(app).listen(port, function(){
console.log("{ server connection : success }");
});
//Database setup
mongoose.connect('mongodb://localhost/mydb');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
console.log('{ database connection : success}');
});
Upvotes: 3
Views: 1808
Reputation: 31
Your form is multipart, so the req.body cannot retrieve data that is sent from the HTML form. You need to use Multer, it is explained here: https://www.npmjs.com/package/multer
In summary, to handle request from multer. You need to provide configuration to the multer object. Here is a code example, this code takes the request in singleFileUpload and run the upload function. The upload function handles the request through multer configuration. If you want to retrieve data, then you can access it through the request function inside the multer.diskStorage.
Let me know if you want clarifications.
`var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, "public/uploaded_files");
},
filename: function(req, file, cb) {
cb(null, req.files[0].fieldname);
}
});
var upload = multer({ storage: storage }).any();
function singleFileUpload(req, res) {
upload(req, res, err => {
if (err instanceof multer.MulterError) {
return res.status(500).json(err);
} else if (err) {
return res.status(500).json(err);
}
return res.status(200).send(req.file);
});
}`
Upvotes: 0
Reputation: 1806
If you are working with files in node, bodyParser will not work.
Your form needs the following attributes
<form action="/account/edit" method="post" enctype="multipart/form-data"></form>
In node you need to require multer
var multer = require('multer');
// this is a simple reqex filter to check the ext
const imageFilter = (req, file, cb) => {
let regex = new RegExp(/\.(jpg|jpeg|png|gif)$/, "i");
// return error
if (!file.originalname.match(regex)) {
return cb(new Error('Only image files are allowed!'), false);
}
cb(null, true);
};
// define the destination
var storage = multer.diskStorage({
destination: function(req, file, cb) {
pathName = `photos/users/${req.user.dataValues.userid}`;
var p = mkdirSync(pathName) // checks if photos/users exist
if (p === false) {
cb(true, null) // path does not exist
} else {
cb(null, pathName) // path exist
}
},
filename: function(req, file, cb) {
let regex = new RegExp(/\.(jpg|jpeg|png|gif|bmp)$/, "i");
let filename = file.originalname;
let ext_arr = filename.match(regex);
let ext_str = ext_arr[0]; // get ext
cb(null, `${Date.now()}${ext_str}`); // file name is date.ext
}
})
// if no directory, make directory
const mkdirSync = (dirPath) => {
try {
fs.mkdirSync(dirPath) // try it without making anything
} catch (err) {
if (err.code !== 'EEXIST') {
fs.mkdirSync("photos/users") // make directory
try {
fs.mkdirSync(dirPath) // try it now that users directory is made
} catch (err) {
if (err.code !== 'EEXIST') {
return false;
}
}
}
}
}
// makes the directory
const checkUserdirSync = (dirPath) => {
try {
fs.mkdirSync(dirPath)
} catch (err) {
if (err.code !== 'EEXIST') throw err
}
}
Most of that code is to check the directory.
Multer will not create directories for you.
Then you need to tie these functions into an object
You have to tell it the field name to look for
const upload = multer({ fileFilter: imageFilter, storage: storage }).single("profile_pic");
Here is my code for actually handling the post
// saves file to system
function handleProfilePictureUpload(req, res, next) {
upload(req, res, function(err) {
if (err) req["file"] = false;
if (!req["file"]) req["file"] = false;
next();
})
}
Most of this code is standard and documented with multer. I would check out https://github.com/expressjs/multer if you have any issues.
Upvotes: 2