Get value from function then make it global - node.js

How can I get the value from inside the function to use it when posting data to database? Here I want to make the value of imageName inside the multer.diskStorage to be global so I can use it when posting the path to database
var imageName;
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/assets/images');
},
filename: function (req, file, cb) {
if (!file.originalname.match(/\.(png|jpg|jpeg)$/)) {
var err = new Error();
err.code = 'filetype';
return cb(err);
} else {
imageName = Date.now() + '_' + file.originalname;
cb(null, imageName);
}
}
});
router.post('/newsfeeds', parser.single("myfile"), function (req, res) {
newsfeed.path = imageName;
newsfeed.save(function (err) {
});
});

This is a way to implement multer. You can use upload as a function or as a middleware, I use it as a function because it allows me a more detailed handling of errors.
It was not necessary a global variable, in this case at the moment that multer processes the image fills the req.file property with the information of the image, as we overwrite the function filename now in req.file.filename this is the custom value that we need.
const multer = require('multer');
const multerStorage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/assets/images');
},
filename: function (req, file, cb) {
if (!file.originalname.match(/\.(png|jpg|jpeg)$/)) {
var err = new Error();
err.code = 'filetype';
return cb(err);
} else {
const imageName = Date.now() + '_' + file.originalname;
cb(null, imageName);
}
}
});
const upload = multer({ storage: multerStorage }).single('myfile');
router.post('/newsfeeds',(req, res) => {
upload(req, res, function (err) {
if (err || !req.file) {
// An error occurred while loading the image.
return res.status(400);
}
newsfeed.path = req.file.filename;
newsfeed.save(function (err) {
});
});
});
Here you can find a table with the rest of the properties of the image
that you have after multer processes the image. Documentation

Global variables tend to be frowned upon in the programming community, so you should first ask yourself if it's really what you want to do.
If you do decide it's the best approach, though, in Node you can attach a property to the global variable. In the browser, you can attach it to window.
As for your issue with the order of execution (from the OP's comments), you can add a Promise instead of a value to the global scope. Then, anytime you want that value, call .then() on your value, or run it in an async function with await.

Related

How can I get the param?

I'm pretty new working with angular and nodejs. I'm trying to upload files to the server and it is working fine, but I want to put the files on specific folder because I don't want to have files together. So this is my code:
const storage = multer.diskStorage({
console.log('carId ' + req.body.carId) //here show undefined
destination: function (req, file, cb) {
cb(null, DIR);
},
filename: function (req, file, cb) {
FILENAME = Date.now() + path.extname(file.originalname);
cb(null, FILENAME);
}
})
const _upload = multer({ storage: storage }).single('file');
exports.upload = async (req, res) => {
try {
_upload(req, res, (err) => {
if (err) {
res.status(500).send(error.message);
}
else {
this.create(req, res); //in this method I can get the carId by doing req.body.carId
}
})
} catch (error) {
res.status(500).send(error.message);
}
}
In the code, with comments I marc where I can get the value and where not. The idea is in the funtion storage get the carId and put the file on /uploads/13 (13) is the value on req.body.carId
Here is how I create the data:
const form = new FormData();
for (let i = 0; i < this.fileArray.length; i++) {
form.append('file', this.fileArray[i])
form.append('name', this.fileArray[i].name)
form.append('carId', this.carId)
}
In the service I do this:
uploadFile(data: FormData): Observable<any> {
return this._http.post(`${this.apiUrl}/upload`, data).pipe(catchError(this.handleError));
}

How to catch errors in multer

I have read documentation for multer. But the current set up I have in my code is different and this makes difficult for me to understand how to handle errors.
It is important now because it happened (only once) that a file was not stored on the server but the code continued saving info in database as if the storing of the file had worked. But it probably did not.
const multer = require('multer');
var docPath = "path_to_disk_where_to_store_files";
var storage = multer.diskStorage({
inMemory: true,
destination: function (request, file, callback) {
callback(null, docPath);
},
filename: function (request, file, callback) {
//Just a function that creates an unique name with timestamp
renamedFile = helpers.createUniqueName(file.originalname);
callback(null, renamedFile);
}
});
var fileFilter = function (req, file, cb) {
var path = require('path');
var ext = path.extname(file.originalname);
if (file.mimetype !== 'application/pdf' || ext.toLowerCase() != '.pdf') {
req.fileValidationError = 'goes wrong on the mimetype';
return cb(null, false, new Error('goes wrong on the mimetype'));
}
cb(null, true);
};
const multerUploader = multer({storage: storage, fileFilter: fileFilter, limits: { fileSize: maxSize }});
router.post('/save_document',[multerUploader.single('file'),saveDocumentInDb]);
I dont really understand where the if-statement that will check if the upload got an error would fit.
Please refer the following for error handling when using multer:
https://github.com/expressjs/multer#error-handling
Your implementation will be something like this:
const multerUploader = multer({storage: storage, fileFilter: fileFilter, limits: { fileSize: maxSize }});
const upload = multerUploader.single('file');
router.post('/save_document', function (req, res) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
// A Multer error occurred when uploading.
} else if (err) {
// An unknown error occurred when uploading.
}
// Everything went fine and save document in DB here.
})
})

How to import an Excel File with Nodejs?

I am a nodeJS programmer. I want to the import excel file into my mongoDB database table with validation.
Validation like if any field is blank then that record not inserted into database and after importing all data from the file display this record not inserted because that field is blank.
There are many package are available but i am confuse which one is better for import excel file.
So please help me which package to use to import an Excel file. And if a demo code is possible please answer it.
router.post('/transferFiles', function (req, res) {
var neatCsv = require('neat-csv');
var array;
var fs = require('fs');
var storage02 = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
cb(null, Date.now() + file.originalname);
}
});
var upload02 = multer({
storage: storage02
}).single('file');
console.log("req.file");
console.log(req.files);
upload02(req, res, function (err) {
if (err) {
console.log("upload error 1" + err);
}
//console.log(req.file);
/** Multer gives us file info in req.file object */
if (!req.file) {
console.log('No file Passed 1');
return;
}
fs.readFile(req.file.path, async function (err, result02) {
if (err) {
console.error(err);
return;
}
array = await neatCsv(result02);
});
here result02 is added in array.so easily you can data to mongodb with help of json

Nodejs Express Multer file upload - handle response in route based on form data

My current implementation is as follows:
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/images/items/')
},filename: function (req, file, cb) {
let ext = '';
if (file.originalname.split(".").length>1)
ext = file.originalname.substring(file.originalname.lastIndexOf('.'), file.originalname.length);
cb(null, Date.now() + ext)
}
})
...Using route....
app.post('/updateItemImage', upload.single('image'), function (req, res, next) {
console.log('user: ' + req.user.id + ' updating image: ' + req.body.item_id);
})
..Alright. That works. req.body.item_id is present in my route, and multer handles req.file, saving it to disk with a unique filename.
however...
I'd like the item to be saved using multer, only if req.user.id and req.body.item_id have certain values. req.body.item_id is undefined within the scope of:
filename: function (req, file, cb) {
So I can't move my code into this function.
TLDR: post function needs to capture req.body.item_id, and req.file. If req.body.item_id == value than save file and res.send('ok') There's more than one way to skin a cat. What's an option that would work?
EDIT: here is the frontend js:
$scope.uploadFile = function(files) {
var fd = new FormData();
var uploadUrl = '/updateItemImage';
var fd = new FormData();
fd.append("image", files[0]);
fd.append("item_id", '11');
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).then(function (response) {
if (response.data == 'ok') {
return
}
alert('something went wrong')
})
}
EDIT: Swapping the order of parameters so that the body param was first:
fd.append("item_id", '11');
fd.append("image", files[0]);
Resolved my issue. This shouldn't matter!
req.body.item_id is undefined within the scope of:
filename: function (req, file, cb) {
I've already tested it, it worked, the value is not undefined in that scope

NodeJS: 'multer' file upload callback function

I am using 'multer' plugin for file upload. I want to call another function after file upload successfully.
Here my code:
module.exports.uploadFile = upload.single('file', '_id'), function (req, res, next) {
console.log('Uploade Successful');
}
var upload = multer({
storage: multer.diskStorage({
destination: './Media/ChatDocUpload',
filename: function (req, file, cb) {
var dest = './Media/ChatDocUpload';
//query string params
var _chatMessageID = req.query.chatMessageID;
var _ext = file.originalname.substring(file.originalname.indexOf("."));
var _fileName = _chatMessageID + _ext;
cb(null, _fileName);
}
})
});
I want to call my new function after image uploaded. Using this code i can upload image successfully, but not get call callback function.
I need call new function after image uploading completed.
//I need to call this function after image fully uploaded
var uploadSuccessFn = function () {
//code
}
You could maybe change the code to use 2 functions in your POST handler:
module.exports = {uploadFile: uploadFile, afterUpload: afterUpload};
function uploadFile(){
upload.single('file', '_id');
}
function afterUpload(req, res, next) {
console.log('Uploade Successful');
}
var upload = multer({
storage: multer.diskStorage({
destination: './Media/ChatDocUpload',
filename: function (req, file, cb) {
var dest = './Media/ChatDocUpload';
//query string params
var _chatMessageID = req.query.chatMessageID;
var _ext = file.originalname.substring(file.originalname.indexOf("."));
var _fileName = _chatMessageID + _ext;
cb(null, _fileName);
}
})
});
Then simply require the file and use it in the post request handler:
.
.
var imageUpload = require('./handler');
app.post('/image/upload',imageUpload.uploadFile,imageUpload.afterUpload);
.
.
The function (inside the process) when you are calling the process of upload, is the callback fuction just use it . you are written line console.log it means your callback fuction is called when your file is upload but you are not using ..
can be done like this:-
function(req,res){ //callback function
res.json({message:"file uploaded successfully"});
}
it will give you json response.
I suggest that you create your own customized storage engine based on multer:
Multer Storage Engine
Then you just add the customized code after your file has been uploaded. Something like this:
MyCustomStorage.prototype._handleFile = function _handleFile (req, file, cb) {
this.getDestination(req, file, function (err, path) {
if (err) return cb(err)
var outStream = fs.createWriteStream(path)
file.stream.pipe(outStream)
outStream.on('error', cb)
outStream.on('finish', function () {
// Insert here whatever you want to do...
console.log('Successfully Uploaded');
cb(null, {
path: path,
size: outStream.bytesWritten
})
}) })}
Please note that you have to use var fs = require('fs') to make it work. Hope this help.
In your code from where you calling upload put an if condition which checks the checks the callback response. If response null then you can call another function in that condition else show some error.
I guess the function you trying call will show some kind of success message to the user.
try like this
var storage = multer.diskStorage({
destination: function (req, file, cb) {
return cb(null, './Media/ChatDocUpload')
},
filename: function (req, file, cb) {
var _chatMessageID = req.query.chatMessageID;
var _ext = file.originalname.substring(file.originalname.indexOf("."));
var _fileName = _chatMessageID + _ext;
return cb(null, _fileName);
}
})
var upload = multer({ storage: storage })
module.exports.uploadFile = upload.single('file'), function (req, res, next) {
console.log('Uploade Successful');
// you function after uploading images
}

Resources