Runny Yolk
Runny Yolk

Reputation: 1164

Uploading multiple files with Multer

I'm trying to upload multiple images using Multer. It all works as expected except that only one file is being uploaded (the last file selected).

HTML

<form class='new-project' action='/projects' method='POST' enctype="multipart/form-data">
  <label for='file'>Select your image:</label>
  <input type='file' multiple='multiple' accept='image/*' name='uploadedImages' id='file' />
  <span class='hint'>Supported files: jpg, jpeg, png.</span>
  <button type='submit'>upload</button>
</form>

JS

//Define where project photos will be stored
var storage = multer.diskStorage({
  destination: function (request, file, callback) {
    callback(null, './public/uploads');
  },
  filename: function (request, file, callback) {
    console.log(file);
    callback(null, file.originalname)
  }
});

// Function to upload project images
var upload = multer({storage: storage}).any('uploadedImages');

// add new photos to the DB
app.post('/projects', function(req, res){
  upload(req, res, function(err){
    if(err){
      console.log(err);
      return;
    }
    console.log(req.files);
    res.end('Your files uploaded.');
    console.log('Yep yep!');
  });
});

I get the feeling I'm missing something obvious...

EDIT

Code I tried following Syed's help:

HTML

<label for='file'>Select your image:</label>
<input type='file' accept='image/*' name='uploadedImages' multiple/>
<span class='hint'>Supported files: jpg, jpeg, png.</span>
<input type="submit" value="uploading_img">

JS

multer = require('multer'),

var upload = multer();

app.post('/projects', upload.array('uploadedImages', 10), function(req, res, err) {
  if (err) {
    console.log('error');
    console.log(err);
  }
  var file = req.files;
  res.end();
  console.log(req.files);
});

Upvotes: 22

Views: 114072

Answers (3)

Aman Silawat
Aman Silawat

Reputation: 571

Uploading multiple files with Multer

NodeJs Code

Set require files and Storage

const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();
const port = 3000

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, path.join(__dirname, './images/'))
    },
    filename: function (req, file, cb) {
            cb(null, file.fieldname + '-' + Date.now() + file.originalname.match(/\..*$/)[0])
    }
});

Set upload file limit or validataion

const multi_upload = multer({
    storage,
    limits: { fileSize: 1 * 1024 * 1024 }, // 1MB
    fileFilter: (req, file, cb) => {
        if (file.mimetype == "image/png" || file.mimetype == "image/jpg" || file.mimetype == "image/jpeg") {
            cb(null, true);
        } else {
            cb(null, false);
            const err = new Error('Only .png, .jpg and .jpeg format allowed!')
            err.name = 'ExtensionError'
            return cb(err);
        }
    },
}).array('uploadedImages', 2)

Create the main route for uploading

app.post('/projects', (req, res) => {
    multi_upload(req, res, function (err) {
        if (err instanceof multer.MulterError) {
            // A Multer error occurred when uploading.
            res.status(500).send({ error: { message: `Multer uploading error: ${err.message}` } }).end();
            return;
        } else if (err) {
            // An unknown error occurred when uploading.
            if (err.name == 'ExtensionError') {
                res.status(413).send({ error: { message: err.message } }).end();
            } else {
                res.status(500).send({ error: { message: `unknown uploading error: ${err.message}` } }).end();
            }
            return;
        }

        // Everything went fine.
        // show file `req.files`
        // show body `req.body`
        res.status(200).end('Your files uploaded.');
    })
});

Listen port

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
});

HTML code

<form id="form_el" class='new-project' action='/projects' method='POST' enctype="multipart/form-data">
    <label for='file'>Select your image:</label>
    <input type='file' multiple='multiple' accept='image/*' name='uploadedImages' id='file' />
    <span class='hint'>Supported files: jpg, jpeg, png.</span>
    <button type='submit'>upload</button>
</form>

JAVASCRIPT CODE

form_el.addEventListener('submit', async function (e) {
    const files = e.target.uploadedImages.files;
    if (files.length != 0) {
        for (const single_file of files) {
            data.append('uploadedImages', single_file)
        }
    }
});

const submit_data_fetch = await fetch('/projects', {
    method: 'POST',
    body: data
});

Upvotes: 25

Noman
Noman

Reputation: 1487

Here you go for this example:

var multer  = require('multer');
var upload = multer();

router.post('/projects', upload.array('uploadedImages', 10), function(req, res) {
  var file = req.files;
  res.end();
});
<form action="/projects" method="post" enctype="multipart/form-data">
  <input type="file" name="uploadedImages" value="uploading_img" multiple>
  <input type="submit" value="uploading_img">
</form>

Visit for more info about Multer.

Upvotes: 13

Mathias
Mathias

Reputation: 73

My guess is that for each file that you want to upload, you reclick:

<input type='file' multiple='multiple' accept='image/*' name='uploadedImages' id='file' />

If you do this, then only the last file selected will be uploaded, as you overwrite the previous selected files.

To upload multiple files, you have to select them all at once in the file picker.

Upvotes: 4

Related Questions