Preface: using Node.js w/Express to build a blog website and using multer to upload an image to mongoDB.
I have a problem with image data not saving to MongoDB.
When I use enctype="multipart/form-data in my HTML form, I get the following in my terminal
fieldname: 'myImage',
originalname: 'photo_2021-12-27_20-07-58.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: './uploads/',
filename: 'photo_2021-12-27_20-07-58.jpg',
path: 'uploads\\photo_2021-12-27_20-07-58.jpg',
size: 134172
}
Which is correct, the image also uploads into a separate uploads folder which is also correct, however the image data doesn't save to my mongoDB.
However, when I remove enctype="multipart/form-data", I don't have the file data in my terminal, nor does the image upload to the separate folder. However I DO! get the image data in my mongoDB. This is such a weird problem. Can anyone help?
Also, sorry for the amount of code I have just unleashed. If anyone actually takes the time to answer this then thank you!
Routes
const express = require('express');
const router = express.Router();
const blogController = require('../controllers/blogController')
const multer = require('multer');
const storage = multer.diskStorage({
//destination for files
destination: function (request, file, callback) {
callback(null, './uploads/');
},
//add back the extension
filename: function (request, file, callback) {
callback(null, file.originalname);
},
});
const upload = multer({
storage: storage,
});
router.get('/create', blogController.blog_create_get);
router.get('/', blogController.blog_home);
router.post('/', upload.single('myImage') ,blogController.blog_create_post);
router.get('/:id', blogController.blog_details);
router.delete('/:id', blogController.blog_delete_post);
module.exports = router
Controller code
const blog_create_post = (req, res) => {
console.log(req.file);
const blog = new Blog(req.body, {
})
blog.save()
.then(() => {
res.redirect('/blogs')
})
.catch((err) => {
console.log(err);
})
}
Schema
image: {
data: Buffer,
contentType: String
},
const Blog = mongoose.model('Blog', blogSchema)
module.exports = Blog;
Midleware
// Static Files | Middleware
app.use(express.static('Public'));
app.use(express.urlencoded({ extended: true }));
app.use(morgan('dev'))
app.use('/uploads',express.static('uploads'))
HTML form
<form action="/blogs" enctype="multipart/form-data" method="POST">
<label for="image">Select image:</label>
<input type="file" id="image" name="myImage" accept="image/*">
<input type="submit" value = "Upload Photo">
Multer is triggered only when the enctype
of your form is enctype="multipart/form-data"
. Example from their doc:
<form action="/profile" method="post" enctype="multipart/form-data">
<input type="file" name="avatar" />
</form>
When you don't provide this enctype
your req
object contains form data in text, and then it is saved to your database, of course.
In order to save binary data to MongoDB you need to open a file designated by
filename: 'photo_2021-12-27_20-07-58.jpg',
path: 'uploads\\photo_2021-12-27_20-07-58.jpg',
and save it appropriately (as text or binary depending on the format and reqs) to the mongodb. To read file check this answer
Firebase Cloud Functions: PubSub, "res.on is not a function"
TypeError: Cannot read properties of undefined (reading 'createMessageComponentCollector')
Hello may I ask if it is possible to make a MYSQL table to read only? In which I had a table for student records which is to be updated whenever a user/student registers which saves details from the MYSQL database which is non-modifiable due to being read onlyIf...
I run php artisan route:cache ,I didn't notice that this command can only run in production and cause this error when I want to run php artisan route:list
I want to nip in the bud that I have already been through all of the points in this excellent answer here: and will explain why they didn't work and what my problems areI am working through a book by Robert Nystrom called Crafting Interpreters