How to turn a query result into a js variable (Javascript) - javascript

I've been searching for this for a day now and I'm basically hopeless.
All I want to do is export the query result as a string (so dataString basically) so I can import as a string in my external .js file.
module.exports.getKlanten = function(req, res){
console.log("zoekt naar klanten");
pool.connect(function(err, client, done){
if(err){
return console.error('error fetching client from pool', err);
}
client.query("select * from abc.relations limit 5", function(err,result){
done();
if(err){
return console.error('error running query', err);
}
var dataString = JSON.stringify(result.rows);
var count = Object.keys(result.rows).length;
var klanten = result.rows;
res
.status(200)
.render("index", {dataString: dataString, klant: klanten, count: count});
console.log("done");
})
});
}
And what would I have to do in the js file to import the string then? It looks so easy yet I can't seem to get it right.

It would be something like this
module.exports.getKlanten = function(req, res){
console.log("zoekt naar klanten");
return "Hello world"; }
and then in your external .js file, you can import it like this
const myModule = require('./JSFile');
and use it like this
console.log(myModule.getKlanten());
Also, use a return statement so that you have a string in your variable.

I am assuming that you need to use the same function externally somewhere else and also for http handler so split it into three files.
//getKlanten.js
module.exports.getKlanten = function(){
return new Promise(function (resolve, reject) {
pool.connect(function(err, client, done){//make sure pool is avialble here
if(err){
console.error('error fetching client from pool', err);
reject(err);
}
client.query("select * from abc.relations limit 5", function(err,result){
if(err){
console.error('error running query', err);
reject(error);
}
var dataString = JSON.stringify(result.rows);
var count = Object.keys(result.rows).length;
var klanten = result.rows;
var data = {dataString: dataString, klant: klanten, count: count}
resolve(data);
})
});
})
}
//in external.JS
var getKlanten = require('getKlanten');
getKlanten().then(function(object) {
console.log(object);
}, function(err){
console.log(err);
})
//in http handler file
var getKlanten = require('getKlanten');
module.exports = function(req,res) {
getKlanten().then(function(data) {
res
.status(200)
.render("index", data);
});
}

Related

Cannot set headers after they are sent to client Expressjs router

I'm getting error cannot set headers on express js, I think the problem is have to write setHeader, i was set but stil can't, this my code:
router.get('/cek', (req, res) => {
const child = execFile(commandd, ['-c', 'config', 'GSM.Radio.C0']);
child.stdout.on('data',
function (data) {
value = (JSON.stringify(data));
x = value.split('.');
y = JSON.stringify(x[2])
result = y.replace(/\D/g, "");
res.setHeader('Content-Type', 'text/html');
res.send(result);
}
);
child.stderr.on('data',
function (data) {
console.log('err data: ' + data);
}
);
});
I tired to fixing this error for two days, but still cannot, anybody can help?
As stated by Frederico Ibba, this is usually caused after res.send is sent and there is still data being processed... Your workaround for this may simply be to receive all the data before sending it out using res.send. You can try this.
async function executeCommand() {
return new Promise((resolve, reject) => {
const child = execFile(commandd, ['-c', 'config', 'GSM.Radio.C0']);
child.stdout.on('data',
function (data) {
value = (JSON.stringify(data));
x = value.split('.');
y = JSON.stringify(x[2])
result = y.replace(/\D/g, "");
resolve(result);
}
);
child.stderr.on('data',
function (err) { // Renamed data for err for clarification
reject(err);
}
);
});
}
router.get('/url', async (req, res) => {
try {
const result = await executeCommand();
res.setHeader('Content-Type', 'text/html');
res.send(result);
} catch(error) {
// There was an error. I'm throwing a 500
res.sendStatus(500);
}
});
Note that this will be effective only if you are confident that the data is being fired once, as indicated by skirtle

NodeJS Html-pdf: fs.readfilesync how to async/await

I have a problem with my html-pdf document creation. The problem is that often the code runs to fast to complete the process of pdf-docutment creation. The Processes consists out of building an HTML-String by replacing placeholders in an Html file. Below you see the code what happens afterwards.
Object.keys(setter).forEach(function(element, key, _array) {
var regex = new RegExp(element, "g");
data = data.replace(regex, setter[element])
})
var result = data;
fs.writeFile(mergeFileRes, result, 'utf8', function (err) {
if(err) {
console.log(err);
return;
} else {
let html2 = fs.readFileSync(mergeFileRes, 'utf8');
let options = {
format: 'a4' ,
"directory" : "/tmp",
};
if(html2){
pdf.create(html2, options).toStream(function(err, stream2){
if(err) console.log(err);
stream2.pipe(res);
stream2.on('end', function () {
try{
fs.unlink(mergeFileRes)
console.log(3090, "deleted file");
}
catch (err){
console.log(3090, "Did not delete file");
}
});
});
} else {
}
}
});
My problem is that in many cases the html2 variable is not yet created before the pdf.create process starts. This is probably because the readFileSync takes too long to finish.
I was wondering, how can I fix this. How can I make the pdf.create wait for the readFileSync to finish and the html2 variable to be filled.
You can use fs.readFile to read the file asynchronously and html2 will be available within the callback function.
Object.keys(setter).forEach(function(element, key, _array) {
var regex = new RegExp(element, "g");
data = data.replace(regex, setter[element])
})
var result = data;
fs.writeFile(mergeFileRes, result, 'utf8', function (err) {
if(err) {
console.log(err);
return;
} else {
fs.readFile(mergeFileRes, 'utf8', function(err, html2){
if (err) throw err;
let options = {
format: 'a4' ,
"directory" : "/tmp",
};
pdf.create(html2, options).toStream(function(err, stream2){
if(err) console.log(err);
stream2.pipe(res);
stream2.on('end', function () {
try{
fs.unlink(mergeFileRes)
console.log(3090, "deleted file");
}
catch (err){
console.log(3090, "Did not delete file");
}
});
});
});
}
});

Express.js- Calling three Dependent MongoDB queries sequentially for each loop

I have to insert multiple different JSON objects in MongoDB and then check whether the some of the data already exist in the database and run another query based on whether the data exists or not for each JSON Object. How can I do in expressjs? I am using mongojs package for working with MongoDB. The code I typed is below:
app.post('/addcard/:id', function(req, res) {
console.log("Received Add Card Request");
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth();
var day = date.getDate();
var yrval = req.body.yrval;
var monval = req.body.monval;
var dateval = req.body.dateval;
for (var i=0;i<req.body.phone.length;i++){
//console.log(i);
var card = new Card({
cardType : req.body.cardtype,
cardTitle : req.body.cardtitle,
allowMultipleStore : false,
phoneNumber : req.body.phone[i],
messageUser : req.body.message,
expiryDate : new Date(year+yrval,month+monval,day+dateval),
creditPoints : req.body.creditpoints,
punchCount : req.body.punch,
messageReachPunchLimit : req.body.limitmessage,
merchantUsersId : mongoose.Types.ObjectId(req.body.merchantuserid),
merchantId : mongoose.Types.ObjectId(req.params.id)
});
console.log(card);
db.carddata.insert(card, function (err,docInserted){
// console.log(card);
console.log(i);
if (err) throw err;
db.userdata.find({phoneNumber:req.body.phone},function (err,docs){
console.log("hiss");
if (err) throw err;
if (docs.length!=0){
var carduser = new CardUsersAssignment({
cardId : docInserted._id,
userId : docs[0]._id,
remainingCreditPoints : req.body.creditpoints,
remainingPunchCount : req.body.punch
});
db.carduser.insert(carduser,function (err){
console.log(" Card Details saved successfully_existing");
//console.log(i);
})
}//If (docs.length!=0)
else{
console.log(" Card Details saved successfully");
}
})//Finding by PhoneNumber
console.log(i+1);
})//Insert Function
console.log("hi");
} // End of For Loop
res.json({
success:true,
message:"Hello. You did it!"
});
});
This code is written as if I were writing for sequential execution. I know that NodeJS is asynchronous. I tried async.waterfall but it is giving error with the mongodb query function. Any help would be great. I am a NodeJS noob. Links to article which discuss similar scenarios would also be great.
You can achieve this using async library.
There is two way to do it.
Use async each to iterate your data and inside each check data is first check data is already exist or not, based on find result you can return or insert the doc.
It is the same as 1st, the only different is you just can to use waterfall for find and insert.
First Approach:
async.each(req.body.phone, function(data, callback) {
// Create card Info
db.carddata.insert(card, function (err,docInserted){
if (err) {throw err;}
db.userdata.find({phoneNumber:req.body.phone},function (err,docs){
if (err) {throw err;
} else if ( docs.length ){
// create carduser data
db.carduser.insert(carduser,function (err){
if (err) {throw err;}
callback();
}
} else {
console.log(" Card Details saved successfully");
callback();
}
}
}, function(err) {
// if any of the file processing produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
Second Approach:
async.each(req.body.phone, function(data, callback) {
//create card data
let data = {}
data.phone = req.body.phone;
data.docInserted = data.docInserted;
data.cardata = cardData;
async.waterfall([
insertCard,
updateDataFind,
cardDataInsert,
async.apply('insertCard', data)
], function (err, result) {
if(err){
if(err.success){
callback();
}
throw err;
}
callback();
});
}, function(err) {
// if any of the file processing produced an error, err would equal that error
if( err ) {
// One of the iterations produced an error.
// All processing will now stop.
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
}
});
function insertCard(data, callback){
db.carddata.insert(card, function (err,data.docInserted){
if(err){throw err;}
callback(null, data);
}
}
function updateDataFind(data, callback){
db.userdata.find({phoneNumber:data.phone},function (err,docs){
if (err) {throw err;}
else if (docs.length!=0){ callback(null, data); }
else { callback({success:true}) }
}
}
function cardDataInsert(data, callback){
// create card user or pass from data.
db.carduser.insert(carduser,function (err){
if (err) {throw err;}
callback(null, data);
}
}

Node.js: Async fs.writeFile queue is creating race condition?

I am trying to use async with node.js to handle multiple incoming POST requests to edit a JSON file. No matter how I refactor it, it will always make one of the edits and not the other. I though that using async.queue would force the operations to handle sequentially? What am I doing wrong?
My code:
var editHandler = function(task, done) {
var req = task.req;
var res = task.res;
fs.stat( "./app//public/json/" + "data.json", function(err, stat) {
if(err == null) {
console.log('File exists');
} else if(err.code == 'ENOENT') {
console.log("Error");
} else {
console.log('Some other error: ', err.code);
}
});
console.log(req.params.id);
console.log(req.body);
fs.readFile( "./app//public/json/" + "data.json", 'utf8', function (err, data) {
data = JSON.parse( data );
data[req.params.id] = req.body.school;
//console.log( data );
fs.writeFile("./app//public/json/" + "data.json", JSON.stringify(data), function (err){
if(err) {
return console.log(err);
}
})
res.redirect('/');
});
};
//Make a queue for the services
var serviceQ = async.queue(editHandler, 20);
serviceQ.drain = function() {
console.log('all services have been processed');
}
app.post('/edit_school/:id', function(req, res) {
serviceQ.push({req: req, res: res })
})
Thanks in advance for any insights! I am really new to using node.js for anything other than npm/webpack.

nodeJs and express.js pending post request using asyc.waterfall flow control library

My post request is pending on network inspection in google chrome but i have called res.send() to release the post request in the async.waterfall() function to end the post request? Any Hints how can this be achieved ?
Here is my register.js file's code
exports.createUser = function(req,res){
var email1 = req.body.mail.toString();
var password = req.body.password.toString();
async.waterfall([
function(callback){
// verify user in the db
User.find({email:email1},function(err,data){
if (err){
res.send(404);
return callback(err);
}
// user is found
if (data.length != 0){
res.send(404);
return callback(new Error("User Found"));
}
callback();
});
},
// generate salt password
function(callback) {
bcrypt.genSalt(SALT_WORK_FACTOR,function(err,salt){
if (err) return callback(err);
bcrypt.hash(password,salt,function(err,hash){
if (err) return callback(err);
return callback(null,hash);
});
});
},
//generate random string
function(hash,callback){
crypto.randomBytes(48,function(err,buf){
if (err) return callback(err);
var randomString = buf.toString('hex');
return callback(null,hash,randomString);
});
},
// save them in the mongoDb using mongoose
function(hash,randomString,callback){
userModel.email = email1;
userModel.password = hash;
userModel.verificationId = randomString
userModel.save();
callback(null,'done');
}
],function(err){
if (err){
console.log(err);
res.send(404);
} else{
console.log("done");
res.send("200");
}
});
}
Here is my app.js code
// render the registration page
app.get('/users/create',register.renderUserPage);
app.post('/users/create',function(req,res){
register.createUser(req,res);
});

Categories

Resources