Search code examples
node.jsexpressmiddlewaremulter

Express route with specific middleware using Express.Router()


I'm using express router to define my routes, and I need to add a middleware so some routes, just adding the middleware before the callback function ouputs the following error:

Error: Route.post() requires callback functions but got a [object Object]

I'm working with folders as modules, my module is upload, and here's the index.js:

module.exports = (function () {

    var express          = require( 'express' ),
        router           = express.Router(),
        multer           = require( 'multer' ),
        transaction_docs = multer( { dest: './client/public/docs/transactions/' } ),
        product_images   = multer( { dest: './client/public/img/products' } ),
        upload           = require( './upload' );

    router.route( '/upload/transaction-docs' )
        .post( transaction_docs, upload.post );//If I take off transaction_docs theres no error

    router.route( '/upload/product-images' )
        .post( product_images, upload.post );//Same as above

    return router;

})();

And here's upload.js:

module.exports = (function () {

    function post( request, response ) {

        var filesUploaded = 0;

        if ( Object.keys( request.files ).length === 0 ) {
            console.log( 'no files uploaded' );
        } else {
            console.log( request.files );

            var files = request.files.file1;
            if ( !util.isArray( request.files.file1 ) ) {
                files = [ request.files.file1 ];
            }

            filesUploaded = files.length;
        }

        response.json(
            {
                message: 'Finished! Uploaded ' + filesUploaded + ' files.',
                uploads: filesUploaded
            }
        );

    }

    return {
        post: post
    }

})();

Solution

  • You are using multer in an incorrect way. For middleware you cannot directly use transaction_docs or product_images as they are not functions.

    Since you are planning to upload more than one file, you need to use transaction_docs.array(fieldName[, maxCount]) which means it will accept an array of files, all with the name fieldname. Optionally error out if more than maxCount files are uploaded. The array of files will be stored in req.files.

    Example:

    var express = require('express')
    var multer  = require('multer')
    var upload = multer({ dest: 'uploads/' })
    
    var app = express()
    
    app.post('/profile', upload.single('avatar'), function (req, res, next) {
      // req.file is the `avatar` file 
      // req.body will hold the text fields, if there were any 
    })
    
    app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
      // req.files is array of `photos` files 
      // req.body will contain the text fields, if there were any 
    })
    
    var cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
    app.post('/cool-profile', cpUpload, function (req, res, next) {
      // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files 
      // 
      // e.g. 
      //  req.files['avatar'][0] -> File 
      //  req.files['gallery'] -> Array 
      // 
      // req.body will contain the text fields, if there were any 
    })