Create and download text files- Node.js & React.Js - node.js

As part of my project, I have to create text files which have to be downloaded as a ".txt".
I am using Node.js and React JavaScript, and I have already tried using the Node.js "fs.writeFile", but the browser doesn't recognize the download, the file name is always being called as the folder name and the file is always empty although the variable is a string and not empty.
I'm calling from the client to this function:
app.post("/downloadnetworks", async (req, res) => {
let selectedApps=req.body.selectedApps;
let arr=await sqlFunctions.createByIds(selectedApps);
res.send();
module.exports.createByIds = (productsArray) => {
return new Promise(function(resolve, reject) {
var bulkedString = '';
var product;
for (let obj of productsArray) {
let query = "select * from...........";
con.query(query, function(err, result, fields) {
if (err) throw err;
let stringifiedJson = JSON.stringify(result)
let parsedJson = JSON.parse(stringifiedJson)
The DB data is being added into the variable 'stringifiedJson', and it continues from here:
let parsedJson = JSON.parse(stringifiedJson) //has all the data from the DB
for (let network of parsedJson) {
if (network.certification_Id) {
bulkedString += network.domain_Name + ", " + network.publisher_Id + ", " + network.relationship + ", " + network.certification_Id;
} else {
bulkedString += network.domain_Name + ", " + network.publisher_Id + ", " +
network.relationship;
}
bulkedString += "\n";
product = network.product;
}
})
fs.writeFile('C:\Work\App ads.txt\App-Ads Files\'' + product + '.txt', bulkedString, 'utf8', (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
}
resolve(bulkedString)
})
}

Related

LDAP authentication using ldapjs in nodejs

Am a newbie to node.js, have somewhat figured out the LDAP authentication. Here am trying to retrieve employee ID from the search but none of the search entries are fetched though the passed credentials are bounded successfully , not sure where i'm mislead. If someone could help me out in it would be of a great help!
Below are the result sets of the code snippet:
Reader bind succeeded
Search results length: 0
Search
retval:{"messageID":2,"protocolOp":"LDAPResult","status":0,"matchedDN":"","errorMessage":"","referrals":[],"controls":[]}
No unique user to bind
ldapRoute.route('/ldap').post((req, res, next) => {
var result = "";
var email =req.body.email;
var client = ldap.createClient({
url: 'ldap://******'
});
var opts = {
filter: '(sAMAccountName='+ email + ')',
attributes: ['sAMAccountName']
};
var username = 'ii' + "\\" + email;
client.bind(username, req.body.password, function(err) {
if (err){
result += "Reader bind failed " + err;
res.send(result);
return;
}
else{
result += "Reader bind succeeded\n";
}
client.search('OU=emp,dc=i,dc=ac,dc=com', opts, function(err, searchRes) {
var searchList = []
if (err) {
result += "Search failed " + err;
res.send(result);
return;
}
searchRes.on("searchEntry", (entry) => {
result += "Found entry: " + entry + "\n";
searchList.push(entry);
});
searchRes.on("error", (err) => {
result += "Search failed with " + err;
res.send(result);
});
searchRes.on("end", (retVal) => {
result += "Search results length: " + searchList.length + "\n";
for(var i=0; i<searchList.length; i++)
result += "DN:" + searchList[i].employeeID + "\n";
result += "Search retval:" + retVal + "\n";
if (searchList.length == 1) {
client.bind(searchList[0].employeeID, req.body.password, function(err) {
if (err)
result += "Bind with real credential error: " + err;
else
result += "Bind with real credential is a success";
res.send(result);
}); // client.bind (real credential)
} else {
result += "No unique user to bind";
res.send(result);
}
});
});
});
});
The issue was in the filters and for some strange reasons the 'end' got fired before hitting the 'searchEntry', debugging it helped me to resolve the issue.
//Filter
var opts = {
filter: '(sAMAccountName=' + email+')',
scope: 'sub',
attributes: ['employeeID']
};
//Search
client.search('OU=empl,dc=ii,dc=ac,dc=in', opts, function(err, searchRes)
{
if (err)
{
result += "Search failed " + err;
res.send(result);
return;
}else{
searchRes.on("searchEntry", (entry) =>
{
result += "Found entry: " + entry.object.employeeID;
res.send(result);
}
/ ........../
} });

NodeJS itself keeps file EBUSY on Windows?

I created a simple function to process uploaded files. I'm using multer to process the multipart data into files. Then I use the code below to move the files around, and return data so my webpage knows how to display the images.
It seems that somehow NodeJS keeps the files open itself. I also created a function to remove the files, but this will give me an EBUSY error. If I try to remove through Windows, it says that NodeJS has te file locked. When I restart the NodeJS process and then re-request the delete URL, the file is removed correctly.
Is there some way I can force NodeJS to close the file resources? Or is there some other error in my script that I am missing?
I updated node to version 12.4.0 but this didn't help either.
Processing the uploads:
exports.handleFormNotes = async(req, res, next) => {
try {
const configVariables = req.app.get('configVariables');
const uploadSuffix = req.body.uploadFolderSuffix || '';
console.log('upload suffix', uploadSuffix);
if (!req.files.length) {
return;
}
const uploadedFiles = Array();
var destPath = configVariables['FormNotesUploadDirectory'];
if (uploadSuffix !== '')
destPath = destPath + '/' + uploadSuffix;
destPath = path.resolve(destPath);
// mkdirSync returns undefined, so run that first and see if the directory exists second.
if (!fs.mkdirSync(destPath, { recursive: true }) && !fs.existsSync(destPath)) {
console.log(destPath, 'does not exist!');
req.alertHandler.addAlert('Pad om afbeelding op te slaan is niet bereikbaar: ' + destPath, 'danger');
res.render('error');
return;
}
var baseUrlPath = configVariables['FormNotesUploadDocumentRoot'];
if (uploadSuffix != null) {
baseUrlPath = baseUrlPath + '/' + uploadSuffix;
}
for(const uploadedFile of req.files) {
let now = new Date();
let destFilename = getDateTime() + "_" + uploadedFile.originalname;
let destFilenameThumb = 'thumb_' + destFilename;
var fullDestination = path.resolve(destPath + '/' + destFilename);
var fullDestinationThumb = path.resolve(destPath + '/' + destFilenameThumb);
console.log('Copy src:', uploadedFile.path, fullDestination);
fs.copyFileSync(uploadedFile.path, fullDestination);
var unlinkResult = fs.unlinkSync(uploadedFile.path);
console.log('Unlink "' + uploadedFile.path + '", result after upload:', unlinkResult);
var newFileInfo = await sharp(destPath + '/' + destFilename)
.resize({ width: 120 })
.toFile(fullDestinationThumb);
console.log('new file info thumb:', newFileInfo);
uploadedFiles.push({
'fullImg': baseUrlPath + '/' + destFilename,
'thumbImg' : baseUrlPath + '/' + destFilenameThumb,
'original': uploadedFile.originalname
});
}
// Push to backend
const data = {
files: [...uploadedFiles],
uploadSuffix: uploadSuffix
};
// Normally retVal should be the return data from OI. If anything goes wrong, retVal = 'error'
this.saveAttachment(req, res, data);
return res.send(data);
}
catch (err) {
console.log('Error handling from notes:', err);
req.alertHandler.addAlert('Error handling form notes: ' + err);
return 'error';
}
}
Removing the uploads:
exports.rmFormNote = async(req, res, data) => {
let retVal;
try {
const configVariables = req.app.get('configVariables');
const httpPath = req.query.img;
console.log('http path:', httpPath);
// Strip off the document root, but check if they are the same first
const firstPart = httpPath.substring(0, configVariables['FormNotesUploadDocumentRoot'].length);
console.log('same?', firstPart, configVariables['FormNotesUploadDocumentRoot']);
var relPath = httpPath;
if (firstPart == configVariables['FormNotesUploadDocumentRoot']) {
relPath = httpPath.substring(configVariables['FormNotesUploadDocumentRoot'].length + 1);
}
var parts = relPath.split('/');
parts[parts.length-1] = 'thumb_' + parts[parts.length-1];
var thumbPath = parts.join('/');
thumbPath = path.resolve(configVariables['FormNotesUploadDirectory'] + '/' + thumbPath);
console.log('thumbpath: ', thumbPath);
var fullPath = configVariables['FormNotesUploadDirectory'] + '/' + relPath;
var dest = path.resolve(fullPath);
console.log('dest: ', dest);
if (!fs.existsSync(dest))
throw "File not found";
fs.unlink(dest, (err) => {
if (err) throw err;
console.log('File deleted');
});
retVal = { result: true };
}
catch(err) {
console.log('Ohnoo', err);
retVal = { result: false, msg: err };
}
return res.send(retVal);
}
Turns out the thumbnail creator sharp was the problem, as stated in this github issue.
I just had to disable the cache, like so:
sharp.cache(false);
var newFileInfo = await sharp(destPath + '/' + destFilename)
.resize({ width: 120 })
.toFile(fullDestinationThumb);

sqlite3 nodejs - return data synchronously

Every example I can find on sqlite3 and nodejs just writes the data to the console, which is useless - how do I await a data and return it from a calling method ? Lets say I have :
exports.selectData = function(tableName, parameters, successHandler) {
var dbConn = new sqlite3.Database('./data/myAppsData.db');
dbConn.all("SELECT " + parameters + " FROM " + tableName + "", function(err, rows) {
// what to do here ? or somewhere else ?
});
}
How do I get data (rows) to return from selectData ? Or alternatively, using successHandler callback ? (it is undefined where the comment is)
dbConn.all("SELECT " + parameters + " FROM " + tableName + "", function(err, rows) {
return rows // could replace with JSON.stringify(rows) If you want to pass JSON data
});
Or as ionizer said you could return a promise. If you need to use async/await
exports.selectData = function(tableName, parameters, successHandler) {
var dbConn = new sqlite3.Database('./data/myAppsData.db');
return new Promise((resolve, reject) => {
dbConn.all("SELECT " + parameters + " FROM " + tableName + "",
function(err, rows) {
if(err) {
reject (err);
} else {
resolve(rows);
}
});
});
}

Nodejs bluebird promise fails while processing image

//Created a promise for each image size.
var promises = sizes.map(function (size) {
return new Promise(function (resolve, reject) {
var destinationDir = fileUtil.getAbsolutePathOfImage(destinationPath);
fileUtil.createDirectoryIfNotExists(destinationDir);
destinationDir += size.src;
fileUtil.createDirectoryIfNotExists(destinationDir);
//Resize the image.
//console.log('imagefile : ' + JSON.stringify(imageFile));
//console.log('destinationDir: ' + JSON.stringify(destinationDir));
//Called an imageUtil resize method to perform resize.
imageUtil.resize(imageFile, destinationDir, size).then(data => {
var fileName = destinationPath + size.src + '/' + data;
resolve(imageUtil.createImageData(fileName, size.height, size.width));
}).catch(err => {
console.error(err);
return reject(err);
});
});
});
Promise.all(promises)
.then(savedImages => {
console.log('saved Images are: ' + JSON.stringify(savedImages));
return res.status(200).json(savedImages);
}).catch(err => {
console.log('i am here' + JSON.stringify(err.message));
return res.status(400).json(JSON.stringify(err.message));
});
---------------------Resize method of imageutil---------------
var Promise = require('bluebird'),
gm = require('gm'),
path = require('path'),
fs = require('fs');
Promise.promisifyAll(gm.prototype);
module.exports = {
resize(imageFile, destinationPath, size){
if (!imageFile || !destinationPath || !size) {
return;
}
return new Promise(function (resolve, reject) {
// If we just passed callback directly, errors would be fatal
var fileName = fileUtil.getFileName(imageFile);
//console.log('sourceFile : ' + JSON.stringify(imageFile));
//console.log('saveDirectory : ' + JSON.stringify(destinationPath));
//console.log('fileName is :' + fileName);
//Create a write stream.
var writeStream = fs.createWriteStream(destinationPath + '/' + fileName);
//console.log('Saving at location: ' + writeStream.path);
gm(imageFile)
.resize(size.width, size.height, '^')
.gravity('Center')
.crop(size.width, size.height)
.writeAsync(writeStream.path, function (err) {
if (err) {
var error = 'Error while creating image of resolution : ' + size.width + 'x' + size.height + '.';
console.error(JSON.stringify(error));
return reject(new Error(error));
}
});
resolve(fileName);
});
}
};
*It seems like everything went correct and it creates four image file which is corrupted and gave me error later on but request processed succesfully. Console output of my image processing are as follows:
saved Images are: [{"src":"/uploads/300/fhjXFLgqq59F91uFK_2h8GiS.jpg","height":"200","width":"300"},{"src":"/uploads/120/fhjXFLgqq59F91uFK_2h8GiS.jpg","height":"120","width":"120"},{"src":"/uploads/48/fhjXFLgqq59F91uFK_2h8GiS.jpg","height":"48","width":"48"}]
POST /api/upload/image/ 200 51.790 ms - 241
"Error while creating image of resolution : 120x120."
"Error while creating image of resolution : 48x48."
"Error while creating image of resolution : 300x200."*
Since you are already using promisifyAll, you don't need to (and should not) use the Promise constructor. writeAsync already returns a promise - if you don't pass a callback, as that's the requirement for Bluebird being able to pass the callback itself in the right position.
You should be using
module.exports = {
resize(imageFile, destinationPath, size){
if (!imageFile || !destinationPath || !size) {
return Promise.reject(new Error("missing arguments"));
}
var fileName = fileUtil.getFileName(imageFile);
//console.log('sourceFile : ' + JSON.stringify(imageFile));
//console.log('saveDirectory : ' + JSON.stringify(destinationPath));
//console.log('fileName is :' + fileName);
//Create a write stream.
var writeStream = fs.createWriteStream(destinationPath + '/' + fileName);
//console.log('Saving at location: ' + writeStream.path);
var promise = gm(imageFile)
.resize(size.width, size.height, '^')
.gravity('Center')
.crop(size.width, size.height)
.writeAsync(writeStream.path);
return promise.then(function() {
return filename;
}, function (err) {
var error = 'Error while creating image of resolution : ' + size.width + 'x' + size.height + '.';
console.error(error, err);
throw new Error(error);
});
}
};
Similarly, you shouldn't use the Promise constructor antipattern in the call to resize - it already returns a promise:
var promises = sizes.map(function (size) {
var destinationDir = fileUtil.getAbsolutePathOfImage(destinationPath);
fileUtil.createDirectoryIfNotExists(destinationDir);
destinationDir += size.src;
fileUtil.createDirectoryIfNotExists(destinationDir);
//Resize the image.
//console.log('imagefile : ' + JSON.stringify(imageFile));
//console.log('destinationDir: ' + JSON.stringify(destinationDir));
return imageUtil.resize(imageFile, destinationDir, size)
//^^^^^^
.then(data => {
var fileName = destinationPath + size.src + '/' + data;
return imageUtil.createImageData(fileName, size.height, size.width));
}, err => {
console.error(err);
throw err;
});
});

local variable is not changing

I'm using node.js for converting text files to CSV. It works for one file, but when i try process more files fileDestination variable doesn't change. Why? Input files like this: r10_1C_BP1-11_e41-81_10_5X1x9_05_train2.res
I got following console output:
./1_train.csv has been written successufully! r10_1C_BP1-11_e41-81_10_5X1x9_05_train2.res
./1_train.csv has been written successufully! r10_1C_BP1-11_e41-81_1_5X1x9_05_train2.res
/*
* lee archivos *.dat y los convierte *.csv
*/
const fs = require('fs');
const inputDir = './';
const outputDir = './';
function readFiles(inputDir, onError) {
fs.readdir(inputDir, function(err, filenames) {
if (err) {
onError(err);
return;
}
filenames.forEach(function(inputFile) {
// first we arre looking for "right" file name
if (inputFile.search(/res/) != -1) {
console.log('Starting processing ' + inputFile);
convert2csv(inputFile, function(error) {
throw err;
});
}
});
});
}
function convert2csv(filename, onError) {
arrayFromFilename = filename.split('_');
epoca = arrayFromFilename[4];
trainORval = arrayFromFilename[7].replace('2.res', '');
console.log("from convert " + filename + " " + epoca);
fs.readFile(inputDir + filename, 'utf-8', function(err, content) {
if (err) {
onError(err);
return;
}
content = content.replace(/^[^0].*\n/mg, '');
arr = content.split('\n');
pares = arr.filter(function(d, i) {
return i % 2 == 1;
});
content = pares.join('\n');
content = content.replace(/(^[\d.]*) ([\d.]*)/gm, '$1,$2');
fileDestination = outputDir + epoca + '_' + trainORval + '.csv';
console.log("filedestination :" + fileDestination);
fs.writeFile(fileDestination, 'y,x\n', function(err) {
if (err) {
return console.error(err);
}
fs.appendFile(fileDestination, content, function(err) {
if (err) {
return console.error(err);
}
console.log(fileDestination + " has been written successufully!", filename);
});
});
});
}

Resources