I can upload images to my s3 bucket, but have been unable to pass the corresponding file url to my MongoDB database. The best I have been able to do is update my image field with a predefined string name. Specifically, I want to change 'TestURL.png' to match the name of the file being saved in my route 'Date.now().toString() + '-' + file.originalname)' but have been unable to do so.
Note, when I try to access 'req.file' the object comes back empty. Also, if my code looks different than other multer-s3 tutorials its because I haven't been able to find any to work, besides what is being used below.
uploadController.js
import asyncHandler from 'express-async-handler';
import Recipe from '../models/recipeModel.js';
// @description Upload
// @route PUT /api/uploadAWS/:id
// @access Private
const uploadRecipeCoverImage = asyncHandler(async (req, res) => {
const {
recipe_cover_image,
} = req.body
const uid = req.params.id
const recipe = await Recipe.findById(uid)
const uploadImage = { recipe_cover_image: 'TestURL.png' }
Recipe.findByIdAndUpdate(uid, uploadImage, { new: true })
.then((recipe) => res.status(200).json({success:true, recipe:recipe}))
.catch((recipe) => res.status(400).json({success:false, error:err}))
export {
uploadRecipeCoverImage
}
uploadAWSRoutes.js
import express from 'express';
import aws from 'aws-sdk';
import multer from 'multer';
import multerS3 from 'multer-s3';
import path from 'path';
import {
uploadRecipeCoverImage,
} from '../controllers/uploadController.js';
import { protect, admin } from '../middleware/authMiddleware.js';
const router = express.Router();
aws.config.update({
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
region: 'us-west-2',
signatureVersion: 'v4'
})
const s3 = new aws.S3()
function checkFileType(file, cb) {
const filetypes = /jpg|jpeg|png/
const extname = filetypes.test(path.extname(file.originalname).toLowerCase())
const mimetype = filetypes.test(file.mimetype)
if(extname && mimetype) {
return cb(null, true)
} else {
cb('Images only!')
}
}
const upload = multer({
limits: { fileSize: 2000000 },
fileFilter: function(req, file, cb) {
checkFileType(file, cb)
},
storage: multerS3({
s3: s3,
bucket: 'recipebook-recipe-cover-images',
acl: "public-read",
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
cb(null, Date.now().toString() + '-' + file.originalname);
},
}),
})
const singleUpload = upload.any()
router.route('/:id')
.put(singleUpload, protect, uploadRecipeCoverImage)
recipeModel.js (if not clear from above)
import mongoose from 'mongoose';
const recipeSchema = mongoose.Schema(
{
...
recipe_cover_image: {
type: String,
required: true
},
,,,
)
const Recipe = mongoose.model('Recipe', recipeSchema);
export default Recipe;