Multer Uploaded Image - node.js

I am using multer to uplaod images. I can upload them to my database with extension. Everything look perfect but I cannot see them on my webpage.
Also note that my project needs specific images for every different articles that means in every article images changes.
This is my article.js relevant codes:
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/uploads')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer({storage: storage})
// Add Submit POST Route
router.post('/add',upload.single('img'), function(req, res){
req.checkBody('title','Title is required').notEmpty();
//req.checkBody('author','Author is required').notEmpty();
req.checkBody('body','Body is required').notEmpty();
// Get Errors
let errors = req.validationErrors();
if(errors){
res.render('add_article', {
title:'Add Article',
errors:errors
});
} else {
var article = new Article({
title: req.body.title,
author: req.user._id,
img: `uploads/${req.file.filename}`,
body: req.body.body,
});
article.save(function(err){
if(err){
console.log(err);
return;
} else {
res.render('add_article', {
});
}
});
}
});
And:
// Get Single Article
router.get('/:id', function(req, res){
Article.findById(req.params.id, function(err, article){
//User.findById(article.author, function(err, user){
res.render('article', {
article:article,
//imagePath: article.img,
//author: user.name
});
});
});
This is my article.pug:
extends layout
block content
br
//h5 Written by #{author}
h1= article.title
p= article.body
img.img-responsive(src=article.img)
Also I havent forgotten enctype or file upload stuffs in my add_article.pug page. But still I cannot understand why it is not uploading.
This is my console.log(article.img): uploads/image.jpeg
But still I cannot understand why I cannot see them. Every answer will be apreciated.

Related

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

Multer in Node Js

I am trying to use multer module in my website but my doubt is that we are declaring upload as constant const upload =multer({}); but then in the post method, we are using upload (req,res,error) method is it the same object or a different one. Can someone please help me out it would be a great help.
const upload = multer({
storage: storage,
limits:{fileSize: 1000000},
fileFilter: function(req, file, cb){
checkFileType(file, cb);
}
}).single('myImage');`
`app.post('/upload', (req, res) => {
upload(req, res, (err) => {
if(err){
res.render('index', {
msg: err
});
} else {
if(req.file == undefined){
res.render('index', {
msg: 'Error: No File Selected!'
});
} else {
res.render('index', {
msg: 'File Uploaded!',
file: `uploads/${req.file.filename}`
});
}
}
});
});
The upload is defined as object but in the post method we are defining a method

How to access variable stored in POST into GET fnction?

My post method is a part of an API that I am using to upload files and to store them in a folder in a local directory. When the user uploads the file it gets stored in the local directory and the path of the image is logged in the console. I am trying to render the path that is logged in the POST method to the EJS template that I am rendering in the get route. I am new to express and node is there any way I can do this? Here is my code:
const storage = multer.diskStorage({
destination: './upload/images',
filename: (req, file, cb) => {
return cb(null, `${file.fieldname}_${Date.now()}${path.extname(file.originalname)}`)
}
})
const upload = multer({
storage: storage,
limits:{
fileSize: 10485760
}
})
app.post("/upload", upload.single('profile'), (req, res) => {
res.redirect("/main")
let imgPath = req.file.path;
console.log(imgPath);
})
function errHandler(err, req, res, next) {
if (err instanceof multer.MulterError) {
res.json({
success: 0,
message: err.message
})
}
}
app.use(errHandler);
This logs "upload\images\profile_1609158104360.jpg"
My get function in which I am trying to access the loged path from the /upload post route
app.get("/main", function (req, res) {
if (req.isAuthenticated()) {
// res.render("main");
User.find({ "secret": {$ne: null}}, function(err, foundUser, imgPath){
if(err){
console.log(err);
}else{
if(foundUser){
res.render("main", {
usersWithSecrets: foundUser,
usersWithImage: imgPath
});
console.log(imgPath);
}
}
}
);
} else {
res.redirect("/login");
}
});
You cant. On post /upload you return redirect. Than browser makes get /main, which is totally different request.

How to put image into mongodb using node js

I want to put a profile image into the users collection in mongodb, and I'd like to retrieve this image when user fetch his profile.
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now()+ path.extname(file.originalname));
}
});
var upload = multer({ storage: storage });
router.put('/user/profile/img/:email', upload.single('profileimg'), (req, res, next) => {
// console.log(req.file);
Users.findOneAndUpdate({ email: req.params.email }, req.file.filename).then(() => {
Users.findOne({ email: req.params.email }).then((resp, err) => {
res.send(resp);
})
})
})
Image is being saved in upload folder in my api but it's not saved in db.
The second parameter of the findOneAndUpdate function must be an object with the field to update and the value:
Users.findOneAndUpdate({ email: req.params.email }, { profileimg: req.file.filename }).then(...)
You can do it like this code below:
router.put('/user/profile/img/:email', upload.single('profileimg'), async (req, res, next) => {
try {
// check your file is uploaded
// check your field
console.log(req.file);
const result = await Users.findOneAndUpdate({ email: req.params.email }, {$set: { profileimage : req.file.filename}}, { returnOriginal: false})
res.send(result)
} catch(ex) {
res.status(500).send(ex.message);
}
})
Note: For this {$set: { profileimage : req.file.filename}}
profileimage : change with the field in your mongodb
req.file.filename: make sure to console.log(req.file) then, where the field you want to store, use it in here and change this example.
I hope it can help you.

issue with multer not allowing a default image

So I am having an issue with multer that i can't figure out. When I add an item with an image everything works with no issues but if I try to add an item with no image it fails. I have an if statement that will define a default image if req.file is undefined but it fails with the error saying req.file.filename is undefined ... Here is the code
Multer setup:
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, "./public/uploads");
},
filename: function(req, file, callback) {
callback(null, Date.now() + file.originalname);
}
});
var upload = multer({ storage: storage }).single("file");
route:
router.post("/item/add", middleware.isLoggedIn, (req, res) => {
User.findById(req.user._id, (err, user) => {
upload(req, res, err => {
if (err) {
req.flash("error", "failed to upload file");
return res.redirect("/products");
}
var item = new Item();
item.name = req.body.name;
item.description = req.body.description;
item.price = req.body.price;
item.createdBy = { id: req.user._id, username: req.user.username };
if (typeof req.file === undefined) {
item.image = "/uploads/no-img.png";
} else {
item.image = "/uploads/" + req.file.filename;
}
item.save(function(err) {
if (err) {
res.send(err);
}
return res.redirect("/products");
});
});
});
});
So I guess my question is... How would I set this up where it wont fail with no image selected?
Your problem is here:
if (typeof req.file === undefined) {
typeof returns a string.
Your check should be if (typeof req.file === "undefined") {

Resources