Create folder before upload in express js - node.js

How can I create a folder (if the folder does not exist yet) before the image will be uploaded? I always get error ENOENT.
When I try this code:
module.exports = function(router){
router.post('/result', directory.tmp, uploader.single, function(req,res){
//some data manipulation here
});
}
//directory.js
module.exports.tmp = function(req, res, next){
mkdirp('./tmp/' + moment().format('MM-DD-YY') + '/' + moment().format('HH'), function (err) {
if (err) console.error(err)
console.log("==================================");
console.log("tmp folder created");
console.log("==================================");
});
next();
};
Though I used directory.tmp first so it will create a folder if it is not existing, I think uploader.single is executed first that is why I got that error. After receiving the error, then that's the time my app created the folder. So in other words, the file uploaded was not saved. How to fix this so it will create the folder first, then upload the file. Btw, I am using mkdirp and multer.

I would suggest you to do the next(); inside the callback of mkdirp.
Because like you did, why it creates the folder it calls next and goes further and the folder is not yet created. This is why you should wait for folder creation first.
module.exports.tmp = function(req, res, next){
mkdirp('./tmp/' + moment().format('MM-DD-YY') + '/' + moment().format('HH'), function (err) {
if (err) console.error(err)
console.log("==================================");
console.log("tmp folder created");
console.log("==================================");
next();
});
};

Related

How to respond without reloading my current page?

I have Express API which used to upload file to the files directory. Whenever I call my API res.send redirecting to a new page. How can I perform this API with reloading my current page?
app.post('/upload', function(req, res) {
let sampleFile;
let uploadPath;
if (Object.keys(req.files).length == 0) {
res.status(400).send('No files were uploaded.');
return;
}
console.log('req.files >>>', req.files); // eslint-disable-line
sampleFile = req.files.sampleFile;
console.log('lusu', sampleFile); // eslint-disable-line
uploadPath = __dirname + '/uploads/' + sampleFile.name;
sampleFile.mv(uploadPath, function(err) {
if (err) {
return res.status(500).send(err);
}
res.send('File uploaded to ' + uploadPath);
});
});
First of all, I would like to recommend multer package for file upload in node js.
instead of res.send(), try res.status(200).json({message:"successfully uploaded"})
try debugging at front end, suppose you have a function for file upload like below,
function fileUpload(){
http.post('url',{headers:headers}).then(res){
// Try to handle the response here. Do not write anything that reloads the page.
}
}

node, sails how to upload same file into two paths

I have created a function to upload image to a custom directory https://sailsjs.com/documentation/concepts/file-uploads .
code:
req.file('avatar').upload({
dirname: require('path').resolve(sails.config.appPath, 'assets/images')
},function (err, uploadedFiles) {
if (err) return res.negotiate(err);
return res.json({
message: uploadedFiles.length + ' file(s) uploaded successfully!'
});
});
how can I upload same file into 2 different paths.
the code I have tried:
var imgPathArr;
var dePathWeb = 'd:/images/web';
var dePath = 'd:/images/mobile';
imgPathArr.push(dePathWeb);
imgPathArr.push(dePath);
req.file('file').upload({
dirname: require('path').resolve(imgPathArr[0])
},function (err, uploadedFiles) {
if (err) return res.send(500, err);
console.log("uploadedFiles web " + uploadedFiles[0].fd);
req.file('file').upload({
dirname: require('path').resolve(imgPathArr[1])
},function (err, files) {
if (err) return res.send(500, err);
console.log("files mobile " + files[0].fd);
});
res.send("ok");
});
});
but each and every time the images are saved into a same path.
console:
uploadedFiles web c:\xampp\htdocs\meServer\images\secondNavi\000a073e-cd6c-4758-ab44-54d32ddfc20a.png
.
files mobile c:\xampp\htdocs\meServer\images\secondNavi\000a073e-cd6c-4758-ab44-54d32ddfc20a.png
why it always take the same path. the image is always only upload into the web directory. I'm defining the paths separately using array index.
Just use fsfrom node DOCS to copy this file.
Your code is really messy. Try to modulate that with a Controller + Service helper. Like ImageController dealing with req and res and ImageService to deal with everything else...

Uploading Files in Node

I'm allowing users to upload files and would like to know if it is possible to only allow the user who uploaded their files access to it.
Currently I am just uploading these to a static folder (Public).
Simply put a route to render the file (this will decrease performance)
Save the file as : filename.extension.userid in a non public folder for example a directory named upload.
Put a route to catch the request on the directory upload :
app.get("/upload/:filename", function(req, res){
var fname = req.params.filename;
var userid = req.user.id; // RETRIEVE AUTHENTICATED USER ID
var fullname = fname+"."+userid;
fs.readFile(__dirname+"/../public/upload/"+fullname, 'base64', function(err, data){
if(err || !data) return res.status(404);
res.set('Content-Disposition', 'attachment; filename="'+fname+'"');
res.set('Content-Type', 'application/pdf'); // example for pdf
return res.end(data, 'base64');
});
});
I couldn't find a reason why you were suggesting using another route to handle the upload. I was able to post to the same route. All that I needed to do was include the path and set it accordingly.
var folder = newPath = path.join(__dirname, '..', './uploads')
var newPath = folder + '/' + callback.fileName;
fs.writeFile(newPath, data, function(err) {
if (err) {
console.log(err)
} else {
//Do stuff
}
});
After the file was uploaded I was then able to complete my task.

node.js / expressjs simple file upload issue

I'm working on creating a simple file uploader on a node server with expressjs as the middleware. So far, the server side looks like:
app.post('/upload', function(req, res) {
console.log(req.files);
//Handle the file
fs.readFile(req.files.imageUploader.path, function(err, data) {
var newPath = __dirname;
console.log(newPath);
console.log(data);
fs.writeFile(newPath, data, function(err) {
console.log(err);
res.send("AOK");
});
});
});
Now, the log statement for __dirname is my source directory, as expected (C:\Development\GitHub\ExpressFileUpload), however an error is happening on the upload:
{ [Error: EISDIR, open 'C:\Development\GitHub\ExpressFileUpload']
errno: 28,
code: 'EISDIR',
path: 'C:\\Development\\GitHub\\ExpressFileUpload' }
I've tried changing the newPath to be / and ./ but no change, different errors, but still errors. Is it something to do with the double \\ in the path in the error? Am I missing something simple here? Thanks for the help, let me know if more info is needed.
The __dirname global object is a directory, not a file. Therefore, you can't open it for writing, which is what fs.writeFile() attempts to do in your script, hence the reason you are getting a EISDIR. Assuming you want the file to be written with the same name it was uploaded with, you can do this:
var file = req.files.imageUploader;
fs.readFile(file.path, function(err, data) {
var path = __dirname + '/' + file.name;
fs.writeFile(path, data, function(err) {
});
});

multi client can not upload file at same time in node.js

am using express.js and uploadify to upload large file to node server, everything works fine except when more than one user login and try to upload file at same time, well it still works but it seems that the server can only upload one file at a time, so the user have to wait until the other user finish their uploading, this is so unacceptable.
here is server side code
exports.upload = function(req, res,next){
// console.log( req.body);
// console.log(req.files);
var tmp_path = req.files.product_video.path;
var target_path = 'F:/shopping/shop/' +req.body.shop_id+'/'+ req.files.product_video.name;
fs.rename(tmp_path, target_path, function(err) {
if (err) {
console.log(err)
}
else{
fs.unlink(tmp_path, function() {
if (err){
console.log(err)
}else{
exec("C:/ffmpeg/bin/ffmpeg -i shop/"+ req.body.shop_id+ '/' + req.files.product_video.name + " -ss 00:01:00.00 -r 1 -an -vframes 1 -s 250x150 -f mjpeg shop/"+ req.body.shop_id+ '/' + req.files.product_video.name + "_thumbnail.jpg", function(err){
var data = {
'thum_src':'shop/'+ req.body.shop_id+ '/' + req.files.product_video.name + "_thumbnail.jpg",
'video_name':req.files.product_video.name,
}
res.send(data);
});
}
});
}
});
};
here is front end code
$('#input_product_video').uploadify({
'formData':{'shop_id':$('#shop_id').val()},
'buttonText' : 'add',
'fileSizeLimit' : '100MB',
'fileObjName' : 'product_video',
'uploader' : '/uploads',
'swf' :'/public/javascripts/lib/uploadify/uploadify.swf',
'onUploadSuccess':function(file,data){
console.log(file);
console.log(JSON.parse(data));
console.log(response);
}
});
You shouldn't need the fs.unlink call because fs.rename is going to move the file to the correct path, not copy it, so if fs.rename succeeds, the temporary file will already be gone. Remove the whole fs.unlink block, which doesn't check for an error anyway. Then you need to make sure in every possible path through the code, you are either calling next(err) with an error or calling res.send. It looks like there are code paths in here where you will not respond and will just let the request time out. Make those changes and see if that gets it working.

Resources