1

I'm trying to upload an image file using the Express NodeJS framework but it keeps throwing this error:

Express
500 TypeError: Cannot read property 'image' of undefined

Here's my app.js:

var express = require('express');
var routes = require('./routes');
var uploads = require('./routes/uploads');
var http = require('http');
var path = require('path');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.bodyParser());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.get('/', routes.index);
app.post('/uploads', uploads.uploads);

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

Here's upload.js:

var fs = require("fs");

exports.uploads = function(req, res){
  //console.log(req.files);
  fs.readFile(req.files.image.path, function (err, data) {

    console.log("Request handler upload was called");
    var imageName = req.files.image.name;
    console.log(imageName);

    if(!imageName){

        console.log("There was an error")
        res.redirect("/");
        res.end();

    } else {

      var newPath = __dirname + "/uploads/" + imageName;


      fs.writeFile(newPath, data, function (err) {


        res.redirect("/uploads/" + imageName);

      });
    }
});
}

I've tried the other answers on similar questions including using the bodyParser() function and setting the name parameter of input tag as 'image' in my index.jade.

Is there any other solution possible?

alasin
  • 172
  • 3
  • 15
  • You have a debug line which you have commented out. What happens when you do a `console.log(req.files)`? That should give you an answer. – Munim Feb 02 '14 at 06:54
  • 1
    `req.files` is undefined per the thrown exception. To understand what attributes `req` has, you should `console.log(req)` instead. – hifier Feb 02 '14 at 06:58
  • 1
    Is the `
    `'s [`enctype` set to `"multipart/form-data"`](http://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean)?
    – Jonathan Lonowski Feb 02 '14 at 06:58
  • @Munim `console.log(req.files)` prints `undefined`. – alasin Feb 02 '14 at 08:18
  • @JonathanLonowski Yes. The other attributes associated with it are `action=""` and `method="post"`. – alasin Feb 02 '14 at 08:20
  • @hifier I did that also. Couldn't find an `image` node in `req` object. Or am I supposed to look for something else in that? – alasin Feb 02 '14 at 08:22
  • 1
    I can't say what your request will contain without seeing how your request is built. However, looking at the rest of your code, you're going to have other problems. You might want to take a step back and understand what an upload is. (For example, you won't be able to read the upload data from your local filesystem.) – hifier Feb 02 '14 at 08:35
  • I tried start the app with the code you posted, however I can't figure out what ./routes is supposed to contain: var routes = require('./routes'); var uploads = require('./routes/uploads'); Also can you post a minimal html page, just with this form + input elements? – BogdanBiv Feb 02 '14 at 08:49
  • @hifier Could you please explain me the reason? I'm new to this. – alasin Feb 02 '14 at 12:46
  • @BogdanBiv That code is mostly the default code that is generated after creating a sample Express app. In this case, folder 'routes' contains index.js and upload.js. index.js just sets the title of the page and upload.js handles the image upload request. Here's the page layout in jade: `form(enctype="multipart/form-data" action="" method="post") input(type="file", id = "image", name="image", accept="image/*") form(method='post' action='uploads') input(type='submit' id='tags' value='Upload')` – alasin Feb 02 '14 at 12:50

3 Answers3

2

Two things came to my mind:

  • have you checked you have writing rights into "/uploads/"?
  • check that index.jade -- having two forms on the same page is a sure sign of trouble. There are cases where multiple forms are needed on the same page, but I'm pretty sure they have no business to do in a simple application. This is most likely the reason your browser makes requests with the wrong parameters. You can also spy on the browser using the Chrome Inspector / Firebug, check if the browser does indeed send the wrong parameters.

Should none of the above help you, please see if you can modify this gist https://gist.github.com/bogdanbiv/eec255655c5aca8ae2de to get similar to your use case. It does not work right now because I do not know what to put inside the index module -- require('./index');

Please note that gist does not allow creating folders. I know it's a security nightmare to have the server code in the same folder as the upload folder, but it's just for debugging purposes.

BogdanBiv
  • 1,485
  • 1
  • 16
  • 33
  • My, that depends on the OS you are using: ls -l on most unices (Linux, BSD, Mac) should do the trick. on Windows I don't know. – BogdanBiv Feb 04 '14 at 08:25
0

I just had this issue, and if you look at the logs, the bodyParser() is being deprecated.

https://github.com/senchalabs/connect/wiki/Connect-3.0

They list couple of middleware to use instead. I revised to use "busboy" and it works fine now.

There are examples in the repo https://github.com/mscdex/busboy

  • 1
    Please add the relevant part(s) to your answer, so other can still see it in the future when the links don't work. – Racil Hilan Mar 24 '14 at 00:47
0

You can redirect the user like this:

res.redirect('/images/' + req.file.filename);

the object file contains:

{ fieldname: 'image',
  originalname: 'Final copy.png',
  encoding: '7bit',
  mimetype: 'image/png',
  destination: './public/upload/temp',
  filename: 'image-1460839230171',
  path: 'public/upload/temp/image-1460839230171',
  size: 8441
}
Joe Gasewicz
  • 1,252
  • 15
  • 20