Node.js TypeError: Cannot read property 'file' of undefined

qliq picture qliq · Feb 3, 2016 · Viewed 17.6k times · Source

I'm just learning node.js and have difficulty to make a simple file upload using express and multer.

Here is the form:

Upload Image

In my configure.js I have:

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

And the image.js controller:

create: function(req, res) {
        var saveImage = function() {
            console.log(req.body);
            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, //<line 55 error
                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();
    },

However I get this error when I try to upload an image:

TypeError: Cannot read property 'file' of undefined
    at saveImage (/home/pc/node-dev/test-proj/controllers/image.js:55:37)
    at module.exports.create (/home/pc/node-dev/test-proj/controllers/image.js:76:9)
    at Layer.handle [as handle_request] (/home/pc/node-dev/test-proj/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/pc/node-dev/test-proj/node_modules/express/lib/router/route.js:131:13)
    at Route.dispatch (/home/pc/node-dev/test-proj/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/home/pc/node-dev/test-proj/node_modules/express/lib/router/layer.js:95:5)
    at /home/pc/node-dev/test-proj/node_modules/express/lib/router/index.js:277:22
    at Function.process_params (/home/pc/node-dev/test-proj/node_modules/express/lib/router/index.js:330:12)
    at next (/home/pc/node-dev/test-proj/node_modules/express/lib/router/index.js:271:10)
    at urlencodedParser (/home/pc/node-dev/test-proj/node_modules/body-parser/lib/types/urlencoded.js:95:37)

And when I log the req object, file is not there:

{ title: 'myimage', description: 'something' }

Actually the snippet is just a slightly modified version what I read in this book, which is using outdated express-3. So basically I just updated it with the multer part.

I'm wondering what is wrong here and how to fix it.

Answer

maowtm picture maowtm · Feb 3, 2016

You are using upload.single, which you should use req.file not req.files. To upload multiple files, use upload.array.

Notice that you don't need another .file after req.file. req.file is the uploaded file if you are using upload.single.