Dolan
Dolan

Reputation: 1647

NodeJS TypeError argument should be a Buffer only on Heroku

I am trying to upload an image to store on MongoDB through Mongoose.

I am using multiparty to get the uploaded file.

The code works 100% perfectly on my local machine, but when I deploy it on Heroku, it gives the error:

TypeError: argument should be a Buffer

Here is my code:

exports.create = function (req, res) {
'use strict';

var form = new multiparty.Form();

form.parse(req, function (err, fields, files) {
    var file = files.file[0],
        contentType = file.headers['content-type'],
        body = {};

    _.forEach(fields, function (n, key) {
        var parsedField = Qs.parse(n)['0'];

        try {
            parsedField = JSON.parse(parsedField);
        } catch (err) {}
        body[key] = parsedField;
    });
    console.log(file.path);
    console.log(fs.readFileSync(file.path));

    var news = new News(body);
    news.thumbnail = {
        data: new Buffer(fs.readFileSync(file.path)),
        contentType: contentType
    };
    news.save(function (err) {
        if (err) {
            return handleError(res, err);
        }
        return res.status(201);
    });
});
};

This is the console logs in the above code for HEROKU:

Sep 26 17:37:23 csgowin app/web.1:  /tmp/OlvQLn87yfr7O8MURXFoMyYv.gif 
Sep 26 17:37:23 csgowin app/web.1:  <Buffer 47 49 46 38 39 61 10 00 10 00 80 00 00 ff ff ff cc cc cc 21 f9 04 00 00 00 00 00 2c 00 00 00 00 10 00 10 00 00 02 1f 8c 6f a0 ab 88 cc dc 81 4b 26 0a ... > 

The is the console logs on my LOCAL MACHINE:

C:\Users\DOLAN~1.ADS\AppData\Local\Temp\TsfwadjjTbJ8iT-OZ3Y1_z3L.gif
<Buffer 47 49 46 38 39 61 5c 00 16 00 d5 36 00 bc d8 e4 fe fe ff ae cf df dc ea f1 fd fe fe db e9 f1 ad ce de 46 5a 71 2b 38 50 90 b8 cc 4a 5f 76 9a c3 d7 8f ... >

Does Heroku need any settings or configurations or something?

Upvotes: 0

Views: 1247

Answers (1)

Jimmy Scray
Jimmy Scray

Reputation: 154

Sounds like the object passed is not a buffer when data: new Buffer(fs.readFileSync(file.path)) is executed. Probably a difference in how your local environment is handling file writes or it could be how multiparty is handling streams.

This code works flawlessly for me:

news.thumbnail = {
        media: fs.createReadStream(fileLocation),
        contentType: contentType
                };

But you also have to make sure your file has been saved from upload before you can use the file in the above createReadStream method. Things are inconsistent with Node, sometimes this happens synchronously and sometimes not. Ive used Busboy to handle the fileupload since it handles streams and creates a handler when the file stream is complete. Sorry, based on the above I cannot tell you where your issue is so ive included two solutions for you to try :))

Busboy: https://www.npmjs.com/package/busboy Ive used this after the file has been uploaded to the temp directory in busboy:

    //Handles file upload and stores to a more permanent location.: 
    //This handles streams.
    // request is given by express.
    var busboy = new Busboy({ headers: request.headers });
    var writeStream;
    busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
       writeStream = file.pipe(fs.createWriteStream(saveTo));
  })
    .on('finish', function() {
        writeStream = file.pipe(fs.createWriteStream(saveTo));
        writeStream.on('close', function(){
        //use the file
    });
  });

Upvotes: 1

Related Questions