Creating a Photo Album in expressjs - javascript

I'm trying to create a photo album app in MEVN.
The req.body.ALBUM will become the folder's name then for the req.body.DESCRIPTION is just its description.
What my code accomplished was just it can create the folder but it creates an undefined folder then save the images inside it.
NOTE: I tried to create an empty folder and change the directory to my sample folder and it can successfully save the images there.
Here is my full code that can only create the folder but not saves the images inside it rather it saves the image in the undefined folder.
router.post('/album', (req, res) => {
let sql = "INSERT INTO GALLERY SET ALBUM = ?, DESCRIPTION = ?";
let body = [req.body.ALBUM, req.body.DESCRIPTION]
myDB.query(sql, body, (error, results) => {
if (error) {
console.log(error);
} else {
let directory = `C:\\Users\\user\\Desktop\\project\\myproject\\public\\${req.body.ALBUM}`;
fse.mkdirp(directory, err => {
if (err) {
console.log(err);
} else {
console.log("Success");
}
});
const myStorage = multer.diskStorage({
destination: directory,
filename: function (req, file, cb) {
cb(null, file.originalname + path.extname(file.originalname))
}
});
const myUploads = multer({
storage: myStorage, limits: {
//10 Million
fileSize: 10e6
}
}).array('files', 15);
if (fse.exists(directory)) {
myUploads(req, res, (error) => {
if (error) {
console.log(error);
} else {
res.send("Success")
}
});
}
else {
console.log(false);
}
}
})
})
When it comes to this part, the req.body.ALBUM becomes undefined therefore the images were saved inside undefined folder.
const myStorage = multer.diskStorage({
destination: directory,
filename: function (req, file, cb) {
cb(null, file.originalname + path.extname(file.originalname))
}
});

try this
fse.mkdirp(directory, err => {
if (err) {
console.log(err);
} else {
const myStorage = multer.diskStorage({
destination: directory,
filename: function (req, file, cb) {
cb(null, file.originalname + path.extname(file.originalname))
}
});
}
});
Here you are waiting for first operation to complete

Related

Multer next() funtion not a funtion

I'm developing this server based on this tutorial, https://www.bezkoder.com/angular-12-node-js-express-mysql/ now I'm in need of add some file upload functionalities, using Multer. but each time I try to us it, I get this error:
/home/miguel/Documents/angular_projs/examples/server/node_modules/multer/lib/make-middleware.js:45
next(err)
^
TypeError: next is not a function
at done (/home/miguel/Documents/angular_projs/examples/server/node_modules/multer/lib/make-middleware.js:45:7)
when i use it here:
//File upload configuration
const maxSize = 2 * 1024 * 1024;
let storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "/resources/static/assets/uploads/");
},
filename: (req, file, cb) => {
console.log(file.originalname);
cb(null, file.originalname);
},
});
let uploadFile = multer({
storage: storage,
limits: { fileSize: maxSize },
}).single("file");
/* ---------------------------------------------------------------------------------------------------- */
//Upload Files
exports.file_upload = async (req, res) => {
let number = req.params.number;
try {
await uploadFile(req, res);
if (req.file == undefined) {
return res.status(400).send({ message: "Please upload a file!" });
}
res.status(200).send({
message: "Uploaded the file successfully: " + req.file.originalname,
});
} catch (err) {
if (err.code == "LIMIT_FILE_SIZE") {
return res.status(500).send({
message: "File size cannot be larger than 2MB!",
});
}
res.status(500).send({
message: `Could not upload the file: ${req.file.originalname}. ${err}`,
});
}
//Check if empty
//res.status(200).json({msg:`${s03}`});
};
I've checked other tutorial and it's suppose to work
Try passing in next as a parameter.
...
exports.file_upload = async (req, res, next) => {
let number = req.params.number;
try {
await uploadFile(req, res, next);
...

Image file upload with node.js

I'm trying to adapt my code to upload files, but I'm not getting it, I looked in the community and I didn't understand, I'm still new to this. It always falls on the error json return, do you know what it can be?
File where you have the logic
async img(request, response){
multer({
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "./Uploads")
},
filename: (req, file, cb) => {
cb(null, Date.now().toString() + '-' + file.originalname)
},
fileFilter: (req, file, cb) => {
const extensionImg = ['image/png', 'image/jpg', 'image/jpeg'].find
(formatPermitted => formatPermitted == file.mimetype)
if(extensionImg){
return cb(null, true)
}
return cb(null, false)
}
})
}).single('image')
if(request.file){
return response.status(200).json({erro: false, message: "ok"});
}else{
return response.status(400).json({erro: true, message: "error"});
}
}
File where the route is
const IncidentsController = require('./controllers/IncidentsController');
const routes = express.Router();
routes.post('/uploads', IncidentsController.img)
multer(...).single(...) returns a middleware function. That middleware function that it returns has to be actually called in order to do something.
Typically, you would define the middleware outside a request handler and then use it as middleware on one or more request handlers.
const imgMulterMiddleware = multer({
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "./Uploads")
},
filename: (req, file, cb) => {
cb(null, Date.now().toString() + '-' + file.originalname)
},
fileFilter: (req, file, cb) => {
const extensionImg = ['image/png', 'image/jpg', 'image/jpeg'].find
(formatPermitted => formatPermitted == file.mimetype)
if(extensionImg){
return cb(null, true)
}
return cb(null, false)
}
})
}).single('image');
Then, use that middleware as needed:
routes.post('/uploads', imgMulterMiddleware, (req, res) => {
// do something with req.file here which will be set
// by the middleware if it was successful
if (req.file) {
res.json({erro: false, message: "ok"});
} else {
res.status(400).json({erro: true, message: "error"});
}
});

Get image path with Multer Express Nodejs

I am using Multer to save images but I need to get the path of the image to save it to MongoDB. I am trying to get the path with req.file but it always tells me on the console that it is undefined.
this is my route:
import { Router } from 'express';
import { check, validationResult } from 'express-validator';
const multer = require('multer');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/products')
},
filename: function (req, file, cb) {
cb(null, new Date().toISOString().replace(/:/g, '-') + file.originalname)
}
});
const fileFilter = (req, file, cb) => {
// reject a file
if (file.mimetype === 'image/jpeg' ||file.mimetype === 'image/png') {
cb(null, true);
} else {
cb(null, false);
//cb(new Error('I don\'t have a clue!'))
}
}
const upload = multer(
{ storage: storage,
limits:{
fileSize: 1024 * 1024
},
fileFilter: fileFilter
});
let router = Router();
router.post('/', upload.single('img'),
newProduct
);
And in the new Product controller I am trying to read the req.file but the console tells me that it is undefined:
Controller:
import { Product } from '../models'
let newProduct = async (req, res = response ) => {
console.log('file ' + req.file); //UNDEFINED
try {
let { status, user, ...body } = req.body;
let productDB = await Product.findOne ( { 'name': body.name } );
if (productDB) {
return res.status(400).json({
msg:`El producto ${ productDB.name } ya existe`
})
}
let data = {
...body,
name: body.name,
user: req.user._id
}
let product = new Product( data );
await product.save();
res.status(200).json( product );
} catch (error) {
return res.status(400).json({
error
});
}
}
Console:
Thanks for your help.
you can try to do this in filename instead:
filename: function (req, file, cb) {
req.imageName = new Date().toISOString().replace(/:/g, '-') + file.originalname
cb(null, req.imageName)
}
then there:
console.log('file ' + req.file); //UNDEFINED
//you can get imageName instead
console.log('imageName',req.imageName)
//if you want url to store in database you can do this
//supposing your have images directory in root of your node server
const url = `${req.protocol}://${req.get('host')}/images/${req.body.image}`

Mongo chunks not written

I am using MongoDB, nodeJS, express, multer, jimp and gridFS to upload an image. I first uploaded the image with multer then resized it with jimp then uploaded the jimp buffer to MongoDB now when I delete the multer image an error comes that the file is probably corrupt as the chunks file is not written(i don't know why but it is actually not written when I want to delete it) can any one tell how to achieve this and what is the error in my code.
here is my post route
app.post('/upload', upload.single("file"), (req, res) => {
if(req.file === undefined || req.file === 0 || req.file === ""){
res.redirect("/");
}
console.log(req.file);
filename = req.file.filename;
Jimp.read( "http://localhost:3000/image/" + req.file.filename, (err, image) => {
if (err) {
console.log(err);
}
// .then(lenna => (tpl.clone().write(imgActive)))
image
.resize(500, Jimp.AUTO)
// console.log(img);
image.getBase64(Jimp.AUTO, (error1, base64Image) => {
if(error1){
console.log(error1);
}
const image1 = new Image({
image: base64Image,
User: "Avichal",
forTest: "Hindi1"
});
image1.save(function(error){
if(error){
console.log(error);
}
})
})
})
gfs.remove({ _id: req.file.id, root: 'uploads' }, (err, gridStore) => {
if (err) {
console.log(err);
}
});
res.redirect('/');
});
here is the error:
MongoError: no chunks found for file, possibly corrupt
just a small error I have to put the remove function In the jimp read function the corrected code is:
app.post('/upload', upload.single("file"), (req, res) => {
if(req.file === undefined || req.file === 0 || req.file === ""){
res.redirect("/");
}
console.log(req.file);
filename = req.file.filename;
Jimp.read( "http://localhost:3000/image/" + req.file.filename, (err, image) => {
if (err) {
console.log(err);
}
// .then(lenna => (tpl.clone().write(imgActive)))
image
.resize(500, Jimp.AUTO)
// console.log(img);
image.getBase64(Jimp.AUTO, (error1, base64Image) => {
if(error1){
console.log(error1);
}
const image1 = new Image({
image: base64Image,
User: "Avichal",
forTest: "Hindi1"
});
image1.save(function(error){
if(error){
console.log(error);
}
})
})
gfs.remove({ _id: req.file.id, root: 'uploads' }, (err, gridStore) => {
if (err) {
console.log(err);
}
res.redirect('/');
});
})
});

how to change the directory to save uploaded files in angular 2?

I'm using angular 2 and i have an uploader. the default folder to save the file is in /assets folder. is there any way to change this directory to a file server for example?
this is my .ts code:
uploader: FileUploader = new FileUploader({
url: '/upload/uploadUserImage',
isHTML5: true
});
and this is my .js file in backend:
const storageUserImage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './src/assets/uploads/profile_images/');
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const uploadUserImage = multer({
storage: storageUserImage
}).single('file');
////////////
module.exports = (router) => {
router.post('/uploadUserImage', function (req, res) {
uploadUserImage(req, res, function (err) {
if (err) {
res.json({
error_code: 1,
err_desc: err
});
return;
}
res.json({
error_code: 0,
err_desc: null
});
});
});
Yes according to multer documentation you have destination function in which you may define your path that where it should be stored.
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/../../tmp/my-uploads') // source folder
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})

Categories