Search code examples
node.jsexpressmultercloudinary

Express, Multer, and Cloudinary not returning full cloudinary response


I'm using Multer/multer-storage-cloudinary to upload images directly to Cloudinary rather first uploading it to a local temp directory, then sending it to Cloudinary:

const express = require('express');
const router = express.Router({mergeParams:true});
if (app.get('env') == 'development'){ require('dotenv').config(); }
const crypto = require('crypto');
const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');
const multer = require('multer');
const { storage } = require('../cloudinary');
const upload = multer({storage});

//configure cloudinary upload settings
cloudinary.config({
    cloud_name:process.env.CLOUDINARY_NAME,
    api_key: process.env.CLOUDINARY_API_KEY,
    api_secret: process.env.CLOUDINARY_API_SECRET
});

const storage = new CloudinaryStorage({
    cloudinary: cloudinary,
    folder: ('book_tracker/'+process.env.CLOUDINARY_FOLDER+'posts'),
    allowedFormats: ['jpeg', 'jpg', 'png'],
    filename: function (req, file, cb) {
        let buf = crypto.randomBytes(16);
        buf = buf.toString('hex');
        let uniqFileName = file.originalname.replace(/\.jpeg|\.jpg|\.png/ig, '');
        uniqFileName += buf;
        
        console.log(req.body);
      cb(undefined, uniqFileName );
    }
  });

const middleware = {
    function asyncErrorHandler: (fn) =>
        (req, res, next) => {
            Promise.resolve(fn(req, res, next))
                         .catch(next);
        }
}


/* POST create user page  */
router.post('/register', upload.single('image'), asyncErrorHandler(postRegister));

What I'm running into is that the response I'm getting in req.file is not the full Cloudinary response which includes public_id, etc. Instead it's like this:

{
  fieldname: 'image',
  originalname: 'My Headshot.jpg',
  encoding: '7bit',
  mimetype: 'image/jpeg',
  path: 'https://res.cloudinary.com/<cloudinary_name>/image/upload/v1611267647/<public_id>.jpg',
  size: 379632,
  filename: '<public_id>'
}

It's been a while since I worked with multer-storage-cloudinary, though that storage was taken directly from an old project that would return the correct information. Is there something in multer, or multer-storage-cloudinary, that I need to set in order to put the full cloudinary response into req.file?


Solution

  • The multer-storage-cloudinary package is a third party package that integrates multer and Cloudinary in a streamlined way, but it doesn't expose all possible options or responses from the Cloudinary SDK or API

    In your example, it's not returning the full API response from Cloudinary, but a subset of the fields, because the file object's filename, path, and size properties are taken from the Cloudinary API response (from the public_id, secure_url, and bytes properties of the API response respectively), but the other fields aren't mapped: https://github.com/affanshahid/multer-storage-cloudinary#file-properties

    If you need the full set of response values (or some specific values not mapped already) you can: