Renaming an uploaded file using Multer doesn't work (Express.js)

Vincent Montalieu picture Vincent Montalieu · Aug 24, 2015 · Viewed 27.4k times · Source

I'm trying to upload a file from a HTML form using Express.js and Multer. I've managed to save the file to the desired location (a folder named uploads).

However, I'd like to rename the file while uploading it because, by default, Multer gives it a strange name such as:

5257ee6b035926ca99923297c224a1bb

Might be a hexadecimal time stamp or so but I need a more explicit name in order to call a script on it later.

I've followed the explanation found here but it doesn't do anything more than it used to: uploading the file with the hexa name.

Also, the two events onFileUploadStart and onFileUploadComplete never seem to be triggered as I don't get anything logged in my console.

I am using two separate files for the server and the routing:

app.js

/**
 * Dependencies
 */

var express = require('express');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

/**
 * Importation of routes
 */
var routes = require('./routes/index');
var recog = require('./routes/recog');

/**
 * Express
 */
var app = express();

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// pour contrer les erreurs de cross domain
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', '*');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

/**
 * Routes
 */
app.use('/', routes);
app.use('/recog', recog);

module.exports = app;

recog.js

/**
 * Requirements
 */
var express = require('express');
var router = express.Router();
var multer = require('multer');
var uploads = multer({
    dest: 'uploads/',
    rename: function (fieldname, filename) {
        console.log("Rename...");
        return filename + Date.now();
    },
    onFileUploadStart: function () {
        console.log("Upload is starting...");
    },
    onFileUploadComplete: function () {
        console.log("File uploaded");
    }
});

/**
 * Upload d'une image
 */
router.post('/upload', uploads.single('image'), function (req, res, next) {
    console.log("Front-end is calling");
    res.json({status: 'success', data: 'Fichier chargé.\nOrgane sélectionné : ' + req.body.organ});
});

module.exports = router;

I have been digging around but I can't figure out what the problem is as I am quite new to Node.js and JavaScript in general.

Thanks for your help guys!

Answer

Gaurav Gupta picture Gaurav Gupta · Sep 20, 2015

The usage for Multer has changed.

Currently Multer constructor accepts only three options:

  1. dist/storage
  2. fileFilter
  3. limits

now rename, onFileUploadStart, onFileUploadComplete would not work.

however renaming can be done using DiskStorage

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, '/tmp/my-uploads')
    },
    filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
  }
})

var upload = multer({ storage: storage })

have a look at these links: