ApplePie
ApplePie

Reputation: 1185

Node.js Body-Parser not able to retrieve form input

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

Answers (2)

Shivam Mahajan
Shivam Mahajan

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

Christian4423
Christian4423

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

Related Questions