MULTER: How to let user upload a photo and add additional information (e.g. name) to post request

3k Views Asked by At

I have a basic multer app working here:

https://github.com/EngineeredTruth/multer

Here's the HTML

<html>

<head>
    <title>File upload Node.</title>
</head>

<body>
    <form id="uploadForm" enctype="multipart/form-data" action="/api/photo" method="post">
        <input type="file" name="userPhoto" multiple />
        <input type="submit" value="Upload Image" name="submit">
        <select name="carlist" form="carform">
          <option value="volvo">Volvo</option>
          <option value="saab">Saab</option>
          <option value="opel">Opel</option>
          <option value="audi">Audi</option>
        </select>
        <input type="text" value="title" name="title">
        </br><span id="status"></span>
    </form>
</body>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery.form/3.51/jquery.form.min.js"></script>
<script>
    $(document).ready(function() {
        $('#uploadForm').submit(function() {
            $("#status").empty().text("File is uploading...");
            $(this).ajaxSubmit({
                error: function(xhr) {
                    status('Error: ' + xhr.status);
                },
                success: function(response) {
                    console.log(response)
                    $("#status").empty().text(response);
                }
            });
            return false;
        });
    });
</script>

</html>

Here's the Node/Express server

var express =   require("express");
var bodyParser =    require("body-parser");
var multer  =   require('multer');
var app =   express();
app.use(bodyParser.json());

var storage = multer.diskStorage({
  destination: function (req, file, callback) {
    callback(null, './uploads');
  },
  filename: function (req, file, callback) {
    if( file.mimetype === 'image/jpeg'){
      var name = Date.now() + "." + 'jpg'
    } else if (file.mimetype === 'image/png'){
      var name = Date.now() + "." + 'png'
    }
    callback(null, name);
  }
});

var limits = {
  fileSize: 10000000
}

var upload = multer({ storage : storage, limits : limits }).array('userPhoto',10)
// console.log(upload());

app.get('/',function(req,res){
      res.sendFile(__dirname + "/index.html");
});

app.post('/api/photo', function(req,res){
  // console.log('post request: ',req);
    upload(req,res,function(err) {
      console.log('after upload');
        //console.log(req.body);
        //console.log(req.files);
        if(err) {
            return res.end("Error uploading file: ", err);
        }
        res.end("File is uploaded");
    });
});

app.listen(3000,function(){
    console.log("Working on port 3000");
});

Everything works and the user can upload a picture. However, I want the user to be able to title the photo and also select the type of car is in the picture by selecting one of the cars from the select (dropdown) menu.

I can't seem to find a way to access 'carlist' and 'title' from my node server where the post request is received. When I console.log 'req', I don't see carlist or title anywhere. Is there a way I can get this information to my node server from the form post action?

1

There are 1 best solutions below

0
On

Taken from: https://github.com/expressjs/multer/issues/381

if your file input element is in the top of form then every data below that gets assigned to req.body after your image is uploaded, in the result of which body remains empty while you upload photo.. So take file input element to very bottom of your form so that req.body will have data from other input elements

So basically have the file input at the bottom of the form. Also req.body doesn't appear in the '/api/photo' section, but suddenly appears in the 'destination and 'filename' middleware, which is inside the upload function