formidable handle no uploaded file errors - node.js

Everything is working as expected in my code except if the user has not uploaded a file it crashes my node app.
The error is arising at the fs.rename part, as there is nothing uploaded the app cant rename anything and causes the following:
Error:
EPERM: operation not permitted, rename 'C:\Users\xxx\AppData\Local\Temp\upload_0a145049089fa69e9df64f8d20abb362' -> 'C:\Users\xxx\Dropbox\Automate NodeJS\Login_Register+Submit - 0.01\data\5be13231807fe33f14b2834a\sdS9m'
Im having difficulty searching for my err and how to handle that, If anyone can point me to some resources for how to handle formidable errors and how to stop the process of the user hasn't uploaded anything it would be fantastic.
It's not a production app or anything of the like its just me learning how to deal with multiple functions and a database at once.
router.post('/submit', userisSubbed, userhasTime, (req, res, next0) => {
var userId = req.user._id;
var username = req.user.email;
var isCompleted = 'No'
var jobNumber = generator.generate({
length: 5,
numbers: true
});
// Validate
const errors = req.validationErrors();
if (errors) {
res.render('index', {
errors: errors
});}
else {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var userPath = req.user._id
var dir = './data/' + userPath + '/' + jobNumber + '/';
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}else
{
console.log("Directory already exist");
}
var oldpath = files.filetoupload.path;
var newpath = dir + files.filetoupload.name;
// copy the file to a new location
fs.rename(oldpath, newpath, function (err) {
if (err) throw err;
console.log('renamed complete');
const newJob = new Job({
userId: userId,
username: username,
isCompleted: isCompleted,
filepath: newpath,
jobNumber: jobNumber,
});
Job.createJob(newJob, function(err, job){
if (err) throw err;
console.log(job);
});
req.flash('success_msg', 'Job Submitted...');
res.redirect('/')
});
});
}
});

Related

How can fetch multiple result based on the key from the MongoDB database?

I want to fetch multiple result from MongoDB based on the some keys.
Below is my code:
router.get('/',function(req, res, next) {
var movie = movieModel.find({category:"movies"});
var sports = movieModel.find({category:"sports"});
var news = movieModel.find({category:"news"});
var cartoon = movieModel.find({category:"cartoons"});
var moviesData;
var sportsData;
var newsData;
var cartoonData;
movie.exec(function(err,data){
if(err) throw err;
console.log(data);
moviesData = data;
});
sports.exec(function(err,data){
if(err) throw err;
else {
sportsData = data;
}
})
news.exec(function(err,data){
if(err) throw err;
else {
newsData = data;
}
})
cartoon.exec(function(err,data){
if(err) throw err;
else{
cartoonData = data;
}
})
console.log(moviesData); // line 1
console.log(sportsData);// line 2
console.log(newsData);// line 3
console.log(cartoonData);// line 4
res.render('home', {admin:false,data:moviesData });
});
Here when I console the data inside the function (name.exec()) then it shows correct output , but when I console outside (like in line 1,line 2,line 3,line 4) it shows undefined.
Use the promise form of exec(), and async/await to save yourself from callback hell (which is otherwise documented in the canonical question How do I return the response from an asynchronous call?):
router.get("/", async function (req, res, next) {
var moviesData = await movieModel.find({ category: "movies" }).exec();
var sportsData = await movieModel.find({ category: "sports" }).exec();
var newsData = await movieModel.find({ category: "news" }).exec();
var cartoonData = await movieModel.find({ category: "cartoons" }).exec();
console.log(moviesData);
console.log(sportsData);
console.log(newsData);
console.log(cartoonData);
res.render("home", { admin: false, data: moviesData });
});

fs.stat never finds file

I'm trying to create a function in node that will generate an article page if it can find the requested article's json, but I can't even get fs.stat to tell me that a file exists. I've verified the directory and the filename of the script with the __dirname and __filename globals, but I can't even get my function to find a file that's in the same directory as the script, much less a different directory.
var express = require('express');
var fs = require('fs');
var router = express.Router();
var articlePage = function home(req, res) {
console.log(__dirname + __filename);
fs.stat('foo.txt', function(err, stat) {
if(err == null) {
console.log('File exists');
res.send("filefound"); //this never is triggered
} else if(err.code == 'ENOENT') {
console.log("file does not exist");
res.status(404).send('file not found');
} else {
console.log('Some error has occured');
}
});
};
router.get('/article/:articleName', articlePage);
module.exports = router;

Node.JS downloading hundreds of files simultaneously

I am trying to download more that 100 files at the same time. But when I execute the downloading function my macbook freezes(unable to execute new tasks) in windows also no download(but doesn't freeze) and no download progress in both case(idle network).
Here is my download module:
var express = require('express');
var router = express.Router();
var fs = require('fs');
var youtubedl = require('youtube-dl');
var links = require('../models/Links');
router.get('/', function (req, res, next) {
links.find({dlStatus: false}, function (err, docs) {
if (err) {
console.log(err);
res.end();
} else if (!docs) {
console.log('No incomplete downloads!');
res.end();
} else {
for (var i = 0; i < docs.length; i++) {
//todo scraping
var video = youtubedl(docs[i].url, [], {cwd: __dirname});
// Will be called when the download starts.
video.on('info', function (info) {
console.log('Download started');
console.log(info);
});
video.pipe(fs.createWriteStream('./downloads/' + docs[i].id + '-' + i + '.mp4'));
video.on('complete', function complete(info) {
links.findOneAndUpdate({url: info.webpage_url}, {dlStatus: true}, function (err, doc) {
if (err)console.log(err);
else console.log('Download completed!')
});
});
}
}
});
});
module.exports = router;
Now can anyone please help me here? I am using this module for downloading files.
The solution is using async in this case.
Try it this way....with async.each()
var express = require('express');
var router = express.Router();
var fs = require('fs');
var youtubedl = require('youtube-dl');
var links = require('../models/Links');
var async = require('async')
router.get('/', function (req, res, next) {
links.find({dlStatus: false}, function (err, docs) {
if (err) {
console.log(err);
res.end();
} else if (!docs) {
console.log('No incomplete downloads!');
res.end();
} else {
async.each(docs,function(doc,cb){
var video = youtubedl(doc.url, [], {cwd: __dirname});
// Will be called when the download starts.
video.on('info', function (info) {
console.log('Download started');
console.log(info);
});
video.pipe(fs.createWriteStream('./downloads/' + docs.id + '-' + i + '.mp4'));
video.on('complete', function complete(info) {
links.findOneAndUpdate({url: info.webpage_url}, {dlStatus: true}, function (err, doc) {
if (err){
console.log(err);
cb(err);
}
else {
console.log('Download completed!');
cb()
}
});
});
},function(err){
if(err)
return console.log(err);
console.log("Every thing is done,Here!!");
})
}
});
});
module.exports = router;
And you can process every thing in batch too using async.eachLimits().

Downloading multiple file from ftp site using node js

i am trying to download each file on ftp server from root folder.
what i did is this-
ftpClient.ls(".", function(err, res) {
res.forEach(function(file) {
console.log(file.name);
ftpClient.get("./"+file.name, 'D:/styleinc/ftp/'+file.name, function(hadErr) {
if (hadErr)
console.log(hadErr);
else
console.log('File copied successfully!');
});
});
but on running it gives me error-
{ [Error: connect ECONNREFUSED]
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
msg: 'Probably trying a PASV operation while one is in progress'
}
i have already successfully logged in and authenticated my self on ftp site.....
i don't know what to do please guide me.
This is the chunk of code I used with async.mapLimit to make it work with only one connection concurrently.
'use strict'
var JSFtp = require('jsftp');
var inspect = require('util').inspect;
var fs = require('fs');
var async = require('async');
var ftp = new JSFtp(require('./util/ftp'))
var local = 'EDI/mohawk/OUTBOX/'
var remote = 'OUTBOX'
var gatherFiles = function(dir){
return new Promise(function(resolve, reject){
ftp.ls(dir + '/*', function(err, res) {
if (err) reject(err)
console.log(res)
var files = [];
res.forEach(function(file){
files.push(file.name)
});
resolve(files)
})
})
}
gatherFiles(remote).then(function(files){
console.log(files)
async.mapLimit(files, 1, function(file, callback){
console.log('attempting: ' +remote + file + '->' + local + file)
ftp.get(remote +'/'+ file, local +'/'+ file, function(err){
if(err){
console.log('Error getting ' + file)
callback(err)
}else{
console.log('Got ' + file)
callback()
}
})
}, function(err, res){
if(err){
console.log(err)
}
console.log('updates complete' + res)
})
})

"object is not a function" error during MongoDB document insertion from a CSV stream using async.queue

I'm trying MongoDB document insertion from a CSV stream using async.queue.
But I face this following error. I've tried all the remedies given in similar SO posts.
Exact error message is:
C:\Users\admin\node_modules\mongodb\lib\mongo_client.js:406
throw err
TypeError:object is not a function
at C:\Users\admin\Desktop\mynodefile.js:13:2
at C:\Users\admin\node_modules\mongodb\lib\mongo_client.js:403:11
at process._tickCallback(node.js:355:11)
node.js code I used:
var csv = require('csv');
var async = require('async');
var fs = require('fs');
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017', function(err, db) {
if (err) throw err;
var collection = db.collection('myCSVs');
var queue = async.queue(collection.insert.bind(collection), 5);
csv()
.from.path('./input.csv', { columns: true })
.transform(function (data, index, cb) {
queue.push(data, function (err, res) {
if (err) return cb(err);
cb(null, res[0]);
});
})
.on('error', function (err) {
console.log('ERROR: ' + err.message);
})
.on('end', function () {
queue.drain = function() {
collection.count(function(err, count) {
console.log('Number of documents:', count);
db.close();
});
};
});
});
You haven't mentioned the database name in your MongoClient.connect function call. You can do so like this:
MongoClient.connect('mongodb://localhost:27017/database_name',function(err, db) {
Then you can do:
var collection = db.collection('myCSVs');
If myCSVs is a collection inside database_name
Or you can also do:
MongoClient.connect('mongodb://localhost:27017',function(err, mongoclient) {
var db = mongoclient.db('database_name');
var collection = db.collection('myCSVs');
});
You have to change
var queue = async.queue(collection.insert.bind(collection), 5);
Into:
var q = async.queue(function (task, callback) {
console.log('hello ' + task.name);
callback();
}, 2);
IN this line :
queue.push(data, function (err, res) {
if (err) return cb(err);
cb(null, res[0]);
});
you are calling push with data and with a callback, but its not implemented in your
var queue = async.queue(collection.insert.bind(collection), 5);

Resources