Node.js: How to call a function again from its callback - javascript

I want to create a directory in server. But want to check if one exists already with the same name. If no directory exists then create one with the name provided. Otherwise append a random string to the provided name and recheck if one exists with the new name.
So far, I'm able to write a function that perform the initial check and create one if it doesn't exists. But no idea to run the check again if a directory exists.
var outputDir = __dirname + '/outputfiles/' + values.boxname;
function ensureExists(path, mask, cb) {
if (typeof mask == 'function') {
cb = mask;
mask = 484;
}
fs.mkdir(path, mask, function(err) {
if (err) {
cb(err);
} else cb(null); // successfully created folder
});
}
and calling the function
ensureExists(outputDir, 484, function(err) {
if (err) {
if (err.code == 'EEXIST') {
var outputDir = outputDir + '-' + Date.now();
// NEED Help here to call this function again to run the check again
return console.log("A Folder with same name already exists");
} else {
console.err(err);
};
} else {
console.log("Folder created");
}
});
So, In short I want to create directories in server with unique names..please help me to fix this problem..thanks

function callback(err) {
if (err) {
if (err.code == 'EEXIST') {
var outputDir = outputDir + '-' + Date.now();
// NEED Help here to call this function again to run the check again
ensureExists(outputDir, 484, callback); // Call again
return console.log("A Folder with same name already exists");
} else {
console.err(err);
};
} else {
console.log("Folder created");
}
}
ensureExists(outputDir, 484, callback); // Call first
Or you could merge the functionality into one:
function ensureExists(path, mask, cb) {
if (typeof mask == 'function') {
cb = mask;
mask = 484;
}
fs.mkdir(path, mask, function(err) {
if (err) {
if (err.code == 'EEXIST') {
var newpath = path + '-' + Date.now();
ensureExists(newpath, mask, cb); // rerun with new path
console.log("A Folder with same name already exists");
} else {
console.err(err);
};
} else cb(path); // successfully created folder
});
}

Related

JS - How to return mysql query values properly

I'm pretty new to JS since I've switched from C#.
My Question is how I can return mysql query values without problems.
chat.registerCmd('getid', (player, arg) => {
db.getPlayerPermission(player.socialId, function(permission){
PermissionValue = permission;
});
var vname;
var name;
if(arg.length <= 1) {
chat.send(player, '/getid [Vorname] [Name]');
return;
}
vname = arg[0];
name = arg[1];
db.getCharIdByName(vname, name, function(charid){
chat.send(player, 'Die ID des Spielers ist: ' + charid);
});
});
Is this a good way to return query values?
export function getPlayerPermission(socialid, callback){
connection.query('SELECT permission FROM permissions WHERE socialid=?',socialid, function(err, rows){
if(err){
console.log(err);
return;
}
callback(rows[0].permission);
});
}
You are using a callback-based approach which is completely fine. You can also use promises. With the callback apparoach, you can return both errors and the result of queries. The first argument can be the error while the second argument can be the returned value
export function getPlayerPermission(socialid, callback) {
connection.query('SELECT permission FROM permissions WHERE socialid=?',socialid,
function(err, rows){
if(err){
console.log(err);
callback(err);
return;
}
callback(null, rows[0].permission);
});
}
Now in your other file, you can call the function as follows
chat.registerCmd('getid', (player, arg) => {
db.getPlayerPermission(player.socialId, function(dbErr, permission) {
// since JS is asynchronous, you need to be in callback function to execute the rest of the code after you get the data from first query
if (dbErr) {
console.log(dbErr);
return;
}
// Now permission variable has data returned from the query
PermissionValue = permission;
var vname;
var name;
if(arg.length <= 1) {
chat.send(player, '/getid [Vorname] [Name]');
return;
}
vname = arg[0];
name = arg[1];
db.getCharIdByName(vname, name, function(charid){
chat.send(player, 'Die ID des Spielers ist: ' + charid);
});
});
});

How to implement a for-loop for an SFTP-Server

I am setting up an SFTP-Server with Nodejs with several functions
implemented. (Read, delete, download…)
The problem is, that the server only sees the content of the first
file in the directory he reads. Meaning while I can see all files
lined up with the help of my WinSCP Client, it only opens the
content of the first file. When I click on the second file, it shows
the content of the first again, although the file is named different
and so on. When I try to download the files, same happens; you can
download each file, but as soon as you open them there is the
content of the very first file in my directory. I know that it has
to do with the for-Loop I wasn't able to implement for a while now.
I hope you guys can help with some experience/ expertise.
I used dummy user names and Paths for this website.
session.on("readdir", function(files, responder) {
var i = 0;
responder.on("dir", function() {
**if (results[i])** {
console.warn(now + " Returning file: " + results[i]);
responder.file(results[i]);
**return i++;**
} else {
return responder.end();
}
});
return responder.on("end", function() {
return console.warn(now + " Directory has been read");
});
});
session.on('stat', function(path, statkind, statresponder) {
statresponder.is_file();
statresponder.permissions = 0o777;
statresponder.uid = 1;
statresponder.gid = 1;
statresponder.size = 1234;
});
session.on("readfile", function(path, writestream) {
var i = 0;
**if(results[i])** {
console.log(now + " Reading file: " **+ results[i]);**
return fs.createReadStream("KKK_Files/"+results[i]).pipe(writestream);
}
else {
console.warn(now + " no file to read");
}
})
session.on("delete", function(path, writestream) {
session.sftp(function(err, sftp) {
if (err) throw err;
var i = 0;
fs.unlink("KKK_Files/" **+ results[i],** function(err){
if ( err ) {
console.log( "Error, problem starting SFTP: %s", err );
}
else
{
console.log(now + " all Files have been deleted");
}
});
});
session.on("download", function(path, fastGet) {
var moveTo = "C:/Users/User/Downloads/file.DAT";
if (err) throw err;
var i = 0;
fs.fastGet("KKK_Files/" +
**results[i],**moveTo,function
(err) {if ( err ) {
console.log("Error downloading the file", err);
}
else
{
console.log(now + "Successfully downloaded");
}
});
});
files.forEach(files => {
results.push(files);
});
});
});
});
for**(i=0; i<results.length; i++)** {
console.log(now + " Reading file: " + results[i]);
return fs.createReadStream("KKK_Files/" + results[i]).pipe(writestream);
}if (err) throw err;
You are using local variable i for index variable on your results. This local variable has value 0 each time the event occurs.
// problem with your variable name, change variable names and try to understand scope.
var i = 0;
You may want to use index variable outside of the the event listener. Try with one event at a time.

Node strange user input async behaviour

I am just getting used to Node programming, but I have come across this execution issue which I am slightly confused about.
I am trying to test if a write path already exists and if it does then ask the user for input.
function testPath(fileName) {
fs.exists(path.resolve('.', fileName), function(exists) {
//the filepath already exists, ask for user confirmation
if(exists) {
process.stdin.on('keypress', function (str, key) {
//print result of keypress to console
console.log("str: ", str, " key: ", key);
if ((str.toLowerCase() == "n") || (~["y", "n"].indexOf(str.toLowerCase()))) {
return false;
}
else {
return true;
}
});
}
else {
//the filepath does not already exist - return true
return true;
}
console.log("Filename in the target directory already exists, would you like to overwrite? (y/n)");
});
}
This function as a whole will be be resolved (or not) by a promise called on it.
The message to user and wait for keypress seem to action in the correct way but it sticks in a loop and never returns even on a valid keypress, does anyone know why this would be?
If you want to use it as a promise, you need to return a promise:
function testPath(fileName) {
return new Promise((resolve, reject) => {
fs.exists(path.resolve('.', fileName), function(exists) {
//the filepath already exists, ask for user confirmation
if(exists) {
process.stdin.on('keypress', function (str, key) {
//print result of keypress to console
console.log("str: ", str, " key: ", key);
if ((str.toLowerCase() == "n") || (~["y", "n"].indexOf(str.toLowerCase()))) {
return reject();
}
else {
return resolve();
}
});
}
else {
//the filepath does not already exist - return true
return resolve();
}
console.log("Filename in the target directory already exists, would you like to overwrite? (y/n)");
});
}
})

error in writing text to a file using node js fs?

I have a folder which is in my public folder called errorlogs.I want to append text to a file in that folder without overwriting the file. However, for some reason, I am unable to do that using the fs.appendfile. Please can someone suggest my error. Here is what I tried.It actually creates a file called errorlogsapikey.txt outside my public folder which is not what I want
var filepath = __dirname+'/errorlogs';
ensureExists(__dirname + '/errorlogs', 0744, function(err) {
if (err){
} // handle folder creation error
else {
console.log("we are all good");
var data = "url:" +" "+url+" "+"urlstatus:"+" "+urlstatus+" "+"time:"+ " "+formatted;
fs.appendFile(filepath + apikey+'.txt', data,function(err){
if(err) throw err;
});
}
});
function ensureExists(path, mask, cb) {
if (typeof mask == 'function') { // allow the `mask` parameter to be optional
cb = mask;
mask = 0777;
}
fs.mkdir(path, mask, function(err) {
if (err) {
if (err.code == 'EEXIST') cb(null); // ignore the error if the folder already exists
else cb(err); // something else went wrong
} else cb(null); // successfully created folder
});
}

Passing a variable between functions using jQuery

I am having trouble passing a variable from one function to another.
This code is from a PhoneGap app that I am working on, the idea is a QR code gets scanned using the offlineScan function which calls checkforOfflineTicket to check the local storage for ticket validation and returns the variable ticketCheck to determine whether the ticket is accepted.
My code below:
function checkforOfflineTicket(ticketID){
var ticketCheck = '1';
db = openDatabase(shortName, version, displayName,maxSize);
db.transaction(function(transaction) {
transaction.executeSql('SELECT * FROM tickets where ticketid=(?)', [ticketID],
function(transaction, result) {
if (result.rows.length == '1') {
if(result.rows.item(0)['status'] == '0'){
ticketCheck = 'OK';
}
else if(result.rows.item(0)['status'] == '1'){
ticketCheck = 'DUPLICATE';
}
else{
ticketCheck = 'ERROR';
}
}
else{
ticketCheck = 'NONE';
}
alert('the ticket check is '+ticketCheck);
},function(transaction, error) {
console.log("Error processing SQL: "+error.message);
});
},errorHandler,nullHandler);
return ticketCheck;
};
function offlineScan(){
cordova.plugins.barcodeScanner.scan(
function (result) {
if(!result.cancelled){
if(result.format == "QR_CODE"){
var ticketCheck = 'test';
var ticketID = result.text; // The ticketID is the full url
values=ticketID.split('='); // Split it at = to get the tickethash
one=values[0]; // url
two=values[1]; // hash
ticketCheck = checkforOfflineTicket(two);
alert('ticket check should be '+ ticketCheck);
} // End if result is QR
}
},
function (error) {
alert("Scanning failed: " + error);
}
);
}
The checkforOfflineTicket function is currently returning the alert the ticket check is OK and then second alert in the offlineScan function returns ticket check should be undefined. I have tried returning the variable in different places but no matter where I put it it does not get passed to the offlineScan function.
What am I missing? Thank you for any help!
This is caused by asynchronous method calls in your code. In checkforOfflineTicket the function to fetch the result set and doing the alert is called asynchronously to your offlineScan function. You have to chain your functions to get the correct order of execution. Following shows one possible way of chaining:
function checkforOfflineTicket(ticketID, callback) {
var ticketCheck = '1';
db = openDatabase(shortName, version, displayName,maxSize);
db.transaction(function(transaction) {
transaction.executeSql('SELECT * FROM tickets where ticketid=(?)', [ticketID],
function(transaction, result) {
...
alert('the ticket check is '+ticketCheck);
if (callback) callback();
}, ...
}
}
function offlineScan(){
cordova.plugins.barcodeScanner.scan(
function (result) {
if(!result.cancelled){
if(result.format == "QR_CODE"){
...
ticketCheck = checkforOfflineTicket(two, function() {
alert('ticket check should be '+ ticketCheck);
);
} // End if result is QR
}
},
function (error) {
alert("Scanning failed: " + error);
}
);
}

Categories

Resources