0

I created an Express app in combination with multer to upload items in my Node.js app

What I try to do is select let's say:

Upload 1 - that has a fieldname of upfile1
Upload 2 - that has a fieldname of upfile2
Upload 3 - that has a fieldname of upfile3

basically, I need to select every uploaded filename item of my multi-upload app separately. Every upload needs to be handled differently in the app for different tasks. Let's use console.log as an example I need to do something like:

console.log(req.body.upfile1.filename);
console.log(req.body.upfile2.filename);
console.log(req.body.upfile3.filename);

to select the different items that get's handled in the app using different fieldname that are defined in my views using the name attribute.

below is my code

Views [index.html]

<form id="app-form" method="POST" class="fileupload" method="post" action="app" enctype="multipart/form-data">
<h1>Multi File Uploads</h1>
<input type="file" name="upfile1" value="">
<input type="file" name="upfile2" value="">
<input type="file" name="upfile3" value="">
<input type="submit" />
</form>

NodeJS [app.js]

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

app.post("/app", upload.any(), function(req, res) {
 let files = req.files;
 files.forEach(file => {
   console.log(file.filename);
});
 res.send(req.files);
 res.end();
});

Help would be very appreciated, thanks!

Cody
  • 719
  • 1
  • 10
  • 19
  • The names of the files on `req.body.upfile1` and not `req.files`. Also use a form on the index.html with `
    `
    – Waweru Kamau Aug 31 '18 at 03:12
  • Also don't forget `enctype="multipart/form-data"` – Waweru Kamau Aug 31 '18 at 03:14
  • my form already uses `
    ` I just didn't wrote it in my question. I also tried now your suggestion with `req.body.upfile1` with `console.log("upfile is: " + req.files.upfile);` but it displays `upfile is: undefined` in the console
    – Cody Aug 31 '18 at 14:15
  • I updated now my question and included the form action I have there – Cody Aug 31 '18 at 14:21

1 Answers1

1

Input elements in your markup must be wrapped in a form (they probably are already wrapped in a form element but not shown in your question). You should also set the form's enctype attribute to multipart/form-data.

<form method="post" enctype="multipart/form-data" action="/upload">
    <input type="file" name="upfile1">
    <input type="file" name="upfile2">
    <input type="file" name="upfile3">

    <input type="submit" value="Submit">
</form>

Once that's done you can configure multer and create a route to handle file uploads:

const upload = multer({
  dest: path.join(__dirname, './upload') // You might want to change this according to your preferences
  // Since you're using any(), you might want to set fileFilter to control which files should be uploaded. See: https://github.com/expressjs/multer#filefilter
});

const findFileByFieldname = (files, fieldname) => {
  return files.find(file => file.fieldname === fieldname) || {};
}

app.post("/upload", upload.any(), (req, res) => {     
  const upfile1Filename = findFileByFieldname(req.files, 'upfile1').filename;
  const upfile2Filename = findFileByFieldname(req.files, 'upfile2').filename;
  const upfile3Filename = findFileByFieldname(req.files, 'upfile3').filename;

  res.json({
    upfile1Filename,
    upfile2Filename,
    upfile3Filename,
  });
});

// Example response (Node v8.11.4, Express v4.16.3, Multer v1.3.1)
// {"upfile1Filename":"360726b532a01b0e31832f067b5922c8","upfile2Filename":"144e1298437afb51f36eb37c77814650","upfile3Filename":"4c908da20e770130377e4006db945af6"}
fardjad
  • 20,031
  • 6
  • 53
  • 68
  • thanks, your code displays all `fieldname` with upload `filename` but how can I select them individually later in my code like `console.log("upfile2 file is:" + req.body.upfile2.filename);` to get the `filename` for each selected `fieldname` in this example `upfile2` separately to connect later every `fieldname` upload to a different task in my app? I can't figure out how to select them individually like in my console.log example hope you know how. – Cody Aug 31 '18 at 14:44
  • @Cody I modified the answer and added a function named `findFileByFieldname` that gets an array of Multer file objects and a `fieldname` and finds the file object that has the specified `fieldname` within the passed `files` array. I also modified the route handler to store file names into 3 different variables. Hope that helps. – fardjad Aug 31 '18 at 22:13
  • thanks so much! I like your solution and you really helped me out with this I very appreciate your help a lot! – Cody Sep 01 '18 at 12:37
  • just a small side question, if I upload multiple files using your code just the first file of the`fieldname` get's recognized in console.log can you maybe provide a way to use your code with multi-upload for each `fieldname` only if possible what I mean if `upfile1` contains two files in the file upload only the first file get's recognized just wanted to ask if you can maybe provide a way that it can recognize also more then 1 file for each `fieldname` upload. – Cody Sep 01 '18 at 21:55
  • I started using the `HTML multiple Attribute` like [link](https://www.w3schools.com/Tags/att_input_multiple.asp) to upload more then one file for each `fieldname` but it just recognizes the first file uploaded. Hope you know what I mean and would help with this too thanks again. – Cody Sep 01 '18 at 21:56
  • If the field names are fixed and you want to allow uploading multiple files in your inputs, I suggest you to use `upload.fields` instead of `upload.any`. Have a look at [this](https://stackoverflow.com/questions/36096805/uploading-multiple-files-with-multer-but-from-different-fields) question and the accepted answer. So in my code, you want to replace `upload.any` with `upload.fields`, define fields that can accept multiple files as arrays, and then you can use a similar approach to find the file names for each field. – fardjad Sep 01 '18 at 22:12
  • thanks, I tried it but receive errors can't figure out how to use your `findFileByFieldname` function with the multi upload for each `fieldname` [Here is what I did tried](https://github.com/cody-cody/multer_test1/blob/master/app.js) hope you can help me with this. Can't figure it out. If you can please update your answer with this, that would be really great only if you want. – Cody Sep 02 '18 at 00:01
  • TypeError: files.find is not a function – frustrated-dev Aug 07 '20 at 05:11