multer: Memory storage option is not working.

I am using multer to upload images to my cloudinary account. Since the images will be uploaded to cloud I do not need them to be stored locally in my app. I am using the MemoryStorage option as given in the documentation.

var cloudinary = require('cloudinary');
var multer  = require('multer');
var storage = multer.memoryStorage();
var upload = multer({ storage: storage });
var cloudinaryConfig = require('../config/cloudinary');

router.post('/', upload.single('image'), function(req, res){
    cloudinary.config(cloudinaryConfig.connection);

    cloudinary.uploader.upload(req.file.path,{tags:'basic_sample'},function(err,image){
        if(err){ 
            console.warn('------------------- ERROR: ' + err);
        }
        console.log("* public_id for the uploaded image is generated by Cloudinary's service.");
        console.log("* "+image.public_id);
        console.log("* "+image.url);
    });
});

However while uploading the image is also uploaded to an “uploads” folder. Any idea what the problem is? Thank you.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 17 (3 by maintainers)

Most upvoted comments

i was able to upload it with memory storage. Cloudinary does not directly upload file buffer, i had to covert the buffer into a datauri.

var Datauri = require('datauri'),
storage = multer.memoryStorage(),
 upload = multer({ storage : storage }).single('image');


exports.uploadImage = function (req, res, next) {
  upload(req,res,function(err) {
    var datauri = new Datauri();
    datauri.format('.png', req.file.buffer);
    cloudinary.uploader.upload(datauri.content,
      function(result) {
        if(result.public_id){
         //res.sendStatus(200)
        }else{
          res.sendStatus(500);
        }
      }
    );
  });
};

Sorry for the delay on this, I think what’s happening is that you already have another multer middleware running before the upload.single('image') one. The memory storage doesn’t provide a req.file.path property, but instead gives you a buffer at req.file.buffer.

Can you show how the router object is being used?


The following small example works for me:

const express = require('express')
const multer = require('multer')

const app = express()
const storage = multer.memoryStorage()
const upload = multer({ storage })

app.post('/', upload.single('image'), (req, res) => {
  console.log('Should be undefined:', req.file.path)
  console.log('Should be the buffer:', req.file.buffer)

  res.send('OK')
})

app.get('/', (req, res) => {
  res.type('text/html').send(`
    <html>
    <head>
      <title>Test upload</title>
    </head>
    <body>
      <form method="post" enctype="multipart/form-data">
        <input type="file" name="image" />
        <input type="submit" />
      </form>
    </body>
  </html>
  `)
})

app.listen(3000, () => console.log('http://localhost:3000/'))

@adeelibr There are some instances where you are unable to write to the server’s filesystem (ex. Heroku’s free tier) in that case memoryStorage is the way to go

I still have a issue though, once you upload a buffer. You can’t get a file extension.

You need to use the datauri package @adeelibr

I was able to do it like this.

let upload = multer({  })


.post('/other', upload.any('image', 10), (req, res, next) => {
    const file = req.files[0];
    // For documentation refer the following link
    // https://cloudinary.com/documentation/node_image_upload
    cloudinary.v2.uploader
      .upload_stream({ resource_type: 'raw' }, (error, result) => { 
        console.log(result);
        console.log(error);
      })
      .end(file.buffer);
  })