How to upload file using multer or body-parser

Viewed 29130

I am a NodeJS beginner, following along a book "Web Development with MongoDB and NodeJS". I am stuck at its chapter 6 with 'multer'. When I use multer for file uploads the server throws the following error:

/Users/fk / Documents / imageuploader / node_modules / express / lib / application.js: 209
throw new TypeError('app.use() requires middleware functions'); ^

TypeError: app.use() requires middleware functions

but when I replace it with bodyParser the server fires up but when I click the upload button it gives me the following error on the browser.

500 TypeError: Cannot read property 'file' of undefined

However, it is supposed to redirect me towards another page, where the uploaded file is shown.

Here is my bodyParser code, please see if I am using it correctly because it gives me "body-parser deprecated" at the starting of the server. I've seen other questions like mine and I followed but none of them really work.

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

app.use(bodyParser({
  uploadDir: path.join(__dirname, '../public/upload/temp')
}));

Following code shows how I use multer, just in case if there is something I shouldn't be doing please let me know. Which one would be better in case of uploading files, body-parser or multer?

app.use(multer({
  dest: path.join(__dirname, '../public/upload/temp')
}));


var saveImage = function() {
  var possible = 'abcdefghijklmnopqrstuvwxyz0123456789',
    imgUrl = '';

  for (var i = 0; i < 6; i += 1) {
    imgUrl += possible.charAt(Math.floor(Math.random() * possible.length));
  }

  var tempPath = req.files.file.path,
    ext = path.extname(req.files.file.name).toLowerCase(),
    targetPath = path.resolve('./public/upload/' + imgUrl + ext);

  if (ext === '.png' || ext === '.jpg' || ext === '.jpeg' || ext === '.gif') {
    fs.rename(tempPath, targetPath, function(err) {
      if (err) throw err;
      res.redirect('/images/' + imgUrl);
    });
  } else {
    fs.unlink(tempPath, function() {
      if (err) throw err;

      res.json(500, {
        error: 'Only image files are allowed.'
      });
    });
  }
};
saveImage();

Preceding block of code is the logic that I am using to upload the file. In the error it is referring to 'file' as undefined which is in the following line in the saveImage function. It is unable to get the path and therefore throws error 500 according to the else part of the saveImage function. Why is 'file' undefined here? I dont get it.

var tempPath = req.files.file.path,
4 Answers

I corrected the code of the book "Web Development with MongoDB and NodeJS" as follows:

app.use(multer({dest:path.join(__dirname,'../public/upload/temp')}).any());
.
.
.
.
const tempPath = req.files[0].path,  // Temporary location of uploaded file
ext = path.extname(req.files[0].originalname).toLowerCase(), // Get file extension of the uploaded file
targetPath = path.resolve(`./public/upload/${imgUrl}${ ext}`); // The final path for the image file


The other parts of code remained intact. It worked and I could upload image files. Best wishes, Mehrdad Sheikhan

Code for upload file using Multer and save it to local folder

api- call fileUpload function
fileUpload(req)
    .then(uploadRes => {
        console.log('uploadRes', uploadRes)
    })
    .catch(err => {
        console.log('err', err)
    })


Create file upload service
const multer = require('multer') // import library
const moment = require('moment')
const q = require('q')
const _ = require('underscore')
const fs = require('fs')
let dir = './public'

/** Store file on local folder */
let storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, dir)
    },
    filename: function (req, file, cb) {
        let date = moment(moment.now()).format('YYYYMMDDHHMMSS')
        cb(null, date + '_' + file.originalname.replace(/-/g, '_').replace(/ /g, '_'))
    }
})

/** Upload files */
let upload = multer({ storage: storage }).array('files')

/** Exports fileUpload function */
module.exports = {
    fileUpload: function (req) {
        let deferred = q.defer()

        /** Create dir if not exist */
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir)
            console.log(`\n\n ${dir} dose not exist, hence created \n\n`)
        }

        upload(req, {}, function (err) {
            if (req && (_.isEmpty(req.files))) {
                deferred.resolve({ status: 200, message: 'File not attached', data: [] })
            } else {
                if (err) {
                    deferred.reject({ status: 400, message: 'error', data: err })
                } else {
                    deferred.resolve({
                        status: 200,
                        message: 'File attached',
                        filename: _.pluck(req.files,
                            'filename'),
                        data: req.files
                    })
                }
            }
        })
        return deferred.promise
    }
}
Related