Search code examples
javascriptnode.jsmongodbmongoosemulter

I am trying to store images using Multer and mongoose though data:Buffer


my schema looks like this

const RecipeSchema = mongoose.Schema({
  user: [
    {
      userName: { type: String, required: true },
      userID: { type: String, required: true },
      userPicture: { data: Buffer, type: String, required: true }
    }
  ],
  recipeName: {
    type: String,
    required: true
  },
  created: {
    type: Date,
    required: true
  },
  ingredient: {
    type: String,
    required: true
  },
  rating: {
    type: String
  },
  steps: [
    {
      step: { type: String },
      picture: { type: String }
    }
  ],
  comments: [
    {
      comment: { type: String },
      reply: { type: String }
    }
  ],
  pictures: [
    {
      picture: { data: Buffer, type: String, required: true }
    }
  ]
})

let Recipe = (module.exports = mongoose.model('Recipe', RecipeSchema))

My post method and the multer's settings looks like this.

const multer = require('multer')
const storage = multer.diskStorage({
  destination: './route/uploads',
  filename: function(req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
  }
})
const upload = multer({
  storage: storage,
  limits: { fileSize: 1000000 },
  fileFilter: function(req, file, cb) {
    checkFileType(file, cb)
  }
})

function checkFileType(file, cb) {
  const filetypes = /jpeg|jpg|png|gif/
  const extname = filetypes.test(path.extname(file.originalname).toLowerCase())
  const mimetype = filetypes.test(file.mimetype)
  if (mimetype && extname) {
    return cb(null, true)
  } else {
    cb('Error: Images Only!')
  }
}

router.post('/', upload.array('files', 10), (req, res) => {
  let files = req.files

  var recipe = new Recipe()
  for (const key in files) {
    if (files.hasOwnProperty(key)) {
      console.log(files[key].path)
      const fl = fs.readFileSync(files[key].path)
      recipe.pictures.picture.data = fl
      recipe.pictures.picture.type = 'image/png' // or 'image/png'
    }
  }
  recipe.save()
})

and I am getting this error

TypeError: Cannot set property 'data' of undefined

Even though the pictures are saved, when I am trying to save the path on the buffer it does not allow me. on the mongoose, documentation is not clear now how to initiate buffer.


Solution

  • Do not save image (or file) to database, just save image name.

    Hotfix, but not recomend.

    pictures is a array.

    for (const key in files) {
      if (files.hasOwnProperty(key)) {
        console.log(files[key].path)
        const fl = fs.readFileSync(files[key].path)
        recipe.pictures.push({
          picture: {
            data: fl,
            type: 'image/png'
          }
        })
      }
    }