why image is saving as text file in node js - node.js

Here i'm trying to save the image in database using multer but image type is saving as a text format but not in .png , .jpeg, .jpg format,
PLease help me where i'm doing wrong thanks in advance
Schema:-
module.exports = mongoose => {
const Role = mongoose.model(
"role",
mongoose.Schema(
{
roleType : { type:String },
image: { type: String,
data: Buffer}
}
)
);
return Role;
};
controller (Creating an instance):-
exports.addRoleFields = async (req, res) => {
const rolesList = new Role ({
roleType : req.body.roleType,
roleImg : req.file.path,
});
rolesList
.save(rolesList)
.then(data => {
res.status(200).send({ data, statusCode: "200" });
})
.catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while creating.",
statusCode: "500"
});
})
}
}
routes:-
module.exports = app => {
const multer = require("multer"),
storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'uploads')
},
filename: function(req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
const uploadImg = multer({storage: storage}).single('image');
const roles = require("../controllers/roles.js");
var router = require("express").Router();
router.post("/addRole", uploadImg , roles.addRoleFields);
app.use('/api/roles', router);
};

I simply changed this
filename: function(req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
to
filename: function (req, file, cb) {
cb(null, file.originalname);
}
its working and saving the file

try this for mongodb client
const storage = multer.diskStorage({
destination: async function (req, file, cb) {
let path = 'uploads/' + req.body.path;
if (!fs.existsSync(path)) {
fs.mkdirSync(path, { recursive: true }, (err) => {
if (err) throw err;
});
}
await cb(null, path);
},
filename: function (req, file, cb) {
cb(null, req.body.filename)
}
});
var upload = multer({ storage: storage })
const router = express.Router();
// Upload Image
router.post("/upload", upload.single('image'), (req, res, next) => {
return res.json({
image: req.file.path
});
});
in this upload.single('image'), file should be the name in which formdata carries the file.
in your case,
router.post("/addRole", uploadImg('image'), (req, res)=>{
});

mongoose model
const imgSave = new mongoose.Schema({
img:{
data: Buffer,
contentType: String
}
});

Related

Multer typescript error next(err) is not a function

I am developing a MEAN stack app for photo upload and I'm encountering an issue with the follow error. Currently testing this endpoint with postman, everytime I upload an image to the folder the server will stop running and I recieve this error. Any help would be appreciated
node_modules\multer\lib\make-middleware.js:45make-middleware.js:45
next(err)
^
TypeError: next is not a function
In my post.controller.js
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads');
},
filename: function (req, file, cb) {
cb(null, file.originalname + '-' + Date.now() + '-' + getExtension(file));
},
});
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5,
},
});
const getExtension = (file) => {
// this function gets the filename extension by determining mimetype. To be exanded to support others, for example .jpeg or .tiff
var res = '';
if (file.mimetype === 'image/jpeg') res = '.jpg';
if (file.mimetype === 'image/png') res = '.png';
return res;
};
(exports.create = upload.single('imagePath')),
async (req, res, next) => {
try {
console.log(req.file, req.body);
const { title, date } = req.body;
const imagePath = req.file.path;
const post = new Posts({
title,
date,
imagePath,
});
await post.save();
return res.status(200).json({
success: true,
post,
});
} catch (error) {
return res.status(500).json({
success: false,
message: 'Server Error',
error: error,
});
}
};
And my posts.route.js
const express = require('express');
const PostsController = require('../controllers/posts.controller');
const Auth = require('../auth/auth');
const multer = require('multer');
const route = express.Router();
route.post('/create', Auth.authenticateJWT, (req, res) => {
PostsController.create(req, res);
});
route.get('/', Auth.authenticateJWT, (req, res) => {
PostsController.getAllPosts(req, res);
});
route.get('/:id', Auth.authenticateJWT, (req, res) => {
PostsController.getPost(req, res);
});
module.exports = route;
You should define create as:
exports.create = async (req, res, next) => {
try {
console.log(req.file, req.body);
const { title, date } = req.body;
const imagePath = req.file.path;
const post = new Posts({
title,
date,
imagePath,
});
await post.save();
return res.status(200).json({
success: true,
post,
});
} catch (error) {
return res.status(500).json({
success: false,
message: 'Server Error',
error: error,
});
}
};
Export the upload variable:
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads');
},
filename: function (req, file, cb) {
cb(null, file.originalname + '-' + Date.now() + '-' + getExtension(file));
},
});
exports.upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5,
},
});
And use it as a middleware:
route.post('/create', Auth.authenticateJWT, PostsController.upload('imagePath'), PostsController.create);

Req.body is Empty inside express router

I have this router and I'm using multer to store files. I need to varify is 'Key' Exists in the server. Only after that server will store the file.
router.post('/', (req, res) => {
console.log(req.body.key); // empty here
upload(req, res, async (err) => {
if (err) {
console.log(err);
res.send({ error: err.message });
} else {
console.log(req.body.key); //shows the key
store(req.file.filename, {filename: req.file.filename, downloaded: 0, key: req.body.key});
res.send({ success: true, downlink: req.file.filename});
}
});
});
let storage = multer.diskStorage({
destination: (req, file, cb) => cb(null, 'uploads/'),
filename: (req, file, cb) => {
const filename = `${uuid()}-${file.originalname}`;
cb(null, filename);
}
});
let upload = multer({
storage: storage,
limits: { fileSize: 15000000 },
}).single('file'); //name field name
How can I add a checkpoint to prevent Unauthorized file upload?
https://i.stack.imgur.com/gZAHE.png

Image gets saved as a .txt file

I am using multer to save an image from the client to mongoDB, and then rendering that image to the client as per the requirement.
When attempting to save the image from the frontend, it is getting saved as a .txt document.
How do I save it as a .png? (I am using Express on Node)
var multer = require('multer');
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'src/');
},
filename: function(req, file, cb) {
cb(null, new Date().toISOString().replace(/:/g, '-')+ file.originalname);
}
});
var upload = multer({ storage: storage });
app.post('/test', upload.single('image'), (req, res, next) => {
var obj = {
name: req.body.name,
desc: req.body.desc,
img: {
data: fs.readFileSync(path.join(__dirname + '/src/' + req.file.filename)),
contentType: 'image/png'
}
}
Image.create(obj, (err, item) => {
if (err) {
console.log(err);
}
else {
item.save();
res.redirect('/admin');
}
});
});
Frontend
<img src="data:image/<%=image.img.contentType%>;base64,
<%=image.img.data.toString('base64')%>">
Upon clicking "Save as"
download.txt

Using multer when I upload an image it shows me a message that image has been successfully added but does not added to upload folder

Here's my code to upload and save image in database , when I do this
on postman it gives an error of 'undefined' but 'file uploaded
successfully' and neither did my image/file is stored in upload folder
//multerfile
const multer = require('multer');
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'originalname');
},
filename: (req, file, cb) => {
cb(null, new Date().toISOString().replace(/:/g, '-') + '-' + file.originalname);
}
});
const filefilter = (req, file, cb) => {
if (file.mimetype === 'image/png' || file.mimetype === 'image/jpg'
|| file.mimetype === 'image/jpeg'){
cb(null, true);
}else {
cb(null, false);
}
}
const upload = multer({storage: storage, fileFilter: filefilter});
module.exports = {upload}
//imagedata model
const mongoose=require('mongoose');
const imageSchema=new mongoose.Schema({
fileName: {
type: String,
required: true
},
filePath: {
type: String,
required: true
},
fileType: {
type: String,
required: true
},
fileSize: {
type: String,
required: true
}
}, {timestamps: true});
module.exports=mongoose.model('imagedata', imageSchema);
//post controller
exports.uploadimage = async (req, res, next) => {
try{
const file= req.file;
console.log(file);
res.status(201).json({messsage:"file uploaded successfully"})
}catch(error){
res.status(400).send(error.message)
}
u have not specified the destination where u want to save the file
create a folder named uploads in ur project and make changes as I have mentioned below:
destination: (req, file, cb) => {
cb(null, 'uploads/originalname');
},

file still uploads with multer even after failed form validation

I have a form for adding a product which lets a user input product name, description etc. and also allows an image upload.
In my app.js file which is my entry point, I have:
const fileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads');
},
filename: (req, file, cb) => {
cb(null, new Date().toISOString() + '-' + file.originalname);
}
});
const fileFilter = (req, file, cb) => {
if (
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/jpeg'
) {
cb(null, true);
} else {
cb(null, false);
}
};
app.use(multer({ storage: fileStorage , fileFilter: fileFilter, limits: { fileSize: 100000} }).single('image'));
Here is my controller:
exports.postAddListing = (req, res, next) => {
const title = req.body.title;
const category = req.body.category;
const description = req.body.description;
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).render('account/add-listing', {
pageTitle: 'Add Item',
path: '/account/add-listing',
errorMessage: errors.array(),
successMessage: null,
oldInput: {
title: title,
description: description
}
});
}
const image = req.file;
const imageUrl = image.path;
const product = new Product({
title: title,
category: category,
description: description,
userId: req.user,
datePosted: Date.now(),
imageUrl: imageUrl
});
product.save()
.then(result => {
const successMessage = req.flash('success', 'Item sucessfully added');
res.redirect('/account/add-listing');
})
.catch(err => console.log(err));
};
I am using express-validator for form validation. The problem I have is that if I for example leave all fields empty but choose an image, validation will fire and I will get error messages but the image will still upload. If form validation fails I don't want the image to upload but not sure how to achieve that.

Resources