Synchronous mysql in Node.js - mysql

I know that node.js is event driven and I should do this async but i can't find in my mind a way to do it.
so, i have this
var querystr = "SELECT * FROM groups";
var result = "";
dbClient.query(querystr, function (err, res, fields) {
if (err) {
console.log(err);
return;
}
for(var i in res) {
result = result + "#" +res[i].name + " =";
for (var j in res[i].members.split(",")) {
var memberquery;
if (j.substr(0,1) == "#") {
memberquery = "SELECT name FROM groups WHERE id = "+j.substr(1, j.length-1);
} else {
memberquery = "SELECT username FROM users WHERE id= "+j;
}
dbClient.query(memberquery, function(err, memres, fields) {
var membername = "";
if (typeof memres[0].username == "undefined") {
membername = "#"+memres[0].name;
} else {
membername = memres[0].username;
}
result = result + " " + membername;
});
}
result = result + "\n";
}
});
The issue that makes it sync is the for inside.
basically i'm generating a document in the result variable where i check the groups and tell the members so the expected output is
Group1 = member, member
Group2 = member, member

I usually use a pattern like the one below for this type of problem. In a nutshell: get a list of things then call a function to handle the list; that function calls itself until the list is completed; gather up the results as you go in an accumulator; when the list is empty, return whatever you've accumulated through the callback. It's just another way of accomplishing what #Andrey Sidorov demonstrated in his response.
//cb is (err, res)
function getData(cb){
var querystr = "SELECT * FROM groups";
var result = "";
dbClient.query(querystr, function (err, res, fields) {
if (err)
cb(err);
else {
var groups = [];
for (var ndx in res)
groups = groups.concat(res[ndx].members.split(","));
getMembers(groups, [], cb);
}
});
}
function getMembers(members, sofar, cb){
var member = members.shift();
if (!member)
cb(null, sofar);
else {
var memberquery;
var params;
if (member.substr(0,1) == "#") {
memberquery = "SELECT name FROM groups WHERE id = ?";
params = [member.substr(1, member.length-1)];
} else {
memberquery = "SELECT username FROM users WHERE id = ?";
params = [member];
}
dbClient.query(memberquery, params, function(err, res) {
if (err)
cb(err);
else {
var membername = "";
if (typeof res[0].username == "undefined") {
membername = "#" + res[0].name;
} else {
membername = res[0].username;
}
sofar.push(membername);
getMembers(members, sofar, cb);
}
});
}
}

function do_queries( resultCallback )
{
var querystr = "SELECT * FROM groups";
var result = "";
var num_queries_left = 0;
dbClient.query(querystr, function (err, res, fields) {
if (err) {
console.log(err);
return;
}
// calculate number of invocations of second sub-query
for(var i in res)
num_queries_left += res[i].members.split(",").length;
for(var i in res) {
result = result + "#" +res[i].name + " =";
for (var j in res[i].members.split(",")) {
var memberquery;
if (j.substr(0,1) == "#") {
memberquery = "SELECT name FROM groups WHERE id = "+j.substr(1, j.length-1);
} else {
memberquery = "SELECT username FROM users WHERE id= "+j;
}
dbClient.query(memberquery, function(err, memres, fields) {
var membername = "";
if (typeof memres[0].username == "undefined") {
membername = "#"+memres[0].name;
} else {
membername = memres[0].username;
}
result = result + " " + membername;
num_queries_left--;
if (num_queries_left == 0)
{
resultCallback(result);
return;
}
});
}
result = result + "\n";
}
});
}
do_queries( function(result) {
console.log(result);
});

Related

JSON Call from view to controller and show JSON object data in view in ASP.NET Core 6 MVC

I have written code in an ASP.NET Core 6 controller and calling this from view. This code gives response to my view but I don't know how to parse the data in view.
Previously I was using JsonrequestBehaviour.Allowget which is now deprecated in .NET 6. Please help me for better appraoch of json call which can return any dynamic object.
Here is my controller code:
public IActionResult GetAccountLevelAndCode(Int32 GroupAccountID, Int32 Companyid)
{
string AccountLevels = ""; string Returnerror; string ReturnBranches;
DataTable AL = new GetDataClass().GetAccountNoAndAndLevels(GroupAccountID, Companyid, out Returnerror);
//a = (GLChartOFAccountModel)AL.Rows[0].ConvertDataRowToObject(a);
string Sql = #"select cab.BranchID from GLChartOFAccount ca inner join GLChartOfAccountBranchDetail cab on ca.GLCAID=cab.GLCAID where cab.GLCAID=" + GroupAccountID;
DataTable dt = new DataTable();
dt = StaticClass.SelectAll(Sql).Tables[0];
AccountLevels = JsonConvert.SerializeObject(AL);
ReturnBranches = JsonConvert.SerializeObject(dt);
Returnerror = JsonConvert.SerializeObject(Returnerror);
return Json(new { AccountLevels, ReturnBranches, Returnerror });
}
Following is my view call and response allocation:
function GetAccountNoandLevel() {
var DATA={"GroupAccountID" : $('#isParent').val(), Companyid : #Model.CompanyID }
var execCode = true;
$.ajax({
async: false,
type: "POST",
url: "/GLChartOFAccount/GetAccountLevelAndCode",
data: DATA,
dataType: "json",
success: function (data) {
try {
var c = JSON.parse(data.AccountLevels)
var b = JSON.parse(data.ReturnBranches)
var er = JSON.parse(data.Returnerror)
if (b.length>0) {
$("#BrachIDs option").each(function () {
var idParent = $(this).parent().attr("id");
this.disabled = true;
});
var dataarray = '';
for (var i = 0; i < b.length; i++) {
dataarray += b[i]["BranchID"] + ',';
}
dataarray = dataarray.replace(/,\s*$/, "");
var data = dataarray.split(",");
$("#BrachIDs").val(data);
$("#BrachIDs").change();
if (data.length > 0) {
for (var i = 0; i < data.length; i++) {
$("#BrachIDs option").filter("[value='" + data[i] + "']").attr('disabled', false);
}
}
}
else {
$("#BrachIDs option").each(function () {
var idParent = $(this).parent().attr("id");
this.disabled = false;
});
$("#BrachIDs option:selected").removeAttr("selected");
}
if (ShowErrorOK(er)) {
$('#GLCode').val('');
}else{
RowToFillValues(c)
}
} catch (e) {
//console.log(e + " GetAccountNoandLevel "); document.getElementById("DisplayErrorMessage").innerText = e.message; $('#btnTriggerMessage').click(); execCode = false; return false;
console.log(e + " GetAccountNoandLevel "); console.log(e.message)
}
},
error: function (err) {
//console.log(err.responseText); document.getElementById("DisplayErrorMessage").innerText = "AJAX error in request: " + JSON.stringify(err.statusText + " " + err.status) + " GetAccountNoandLevel::Unable To Get Details"; $('#btnTriggerMessage').click(); execCode = false; return false;
console.log("AJAX error in request: " + JSON.stringify(err.statusText + " " + err.status) + " GetAccountNoandLevel::Unable To Get Details")
}
});
if (execCode) {
}
}
The response data is showing undefined...
you don't need serialize and parse manually, it will be done automaticaly
return new JsonResult(new { AccountLevels=AL, ReturnBranches=dt, Returnerror= Returnerror });
and ajax
var c = data.AccountLevels;
var b = data.ReturnBranches;
var er = data.Returnerror;

Problem with query in foreach loop in node js

I am fetching results from a query and want to pass value from result on the next query. Here is my code. But it's not working, I tried setTimeOut function as well.
dbcon.query('SELECT ci_offers.*, ci_advertisers.id as merchant_id, ci_advertisers.full_name, ci_advertisers.phone, ci_advertisers.companylogo FROM ci_offers, ci_advertisers WHERE ci_offers.advertiser_id = ci_advertisers.id AND ci_offers.is_active=1', function(error, results, fields) {
if (error) throw error;
if (results.length > 0) {
var objectOffer;
var objCoin;
// async.forEachOf(results, function (dataElement, i, inner_callback){
results.forEach((val) => {
objectOffer = jsonParser(val);
var token_id = objectOffer.token_id;
var redeem_coin_grabbed = 0;
if (token_id > 0) {
dbcon.query('SELECT count(id) as coingrabbed FROM ci_grabcoin_details_for_game WHERE user_id = ? AND coin_id= 33', [user_id, token_id], function(error1, results1, fields1) {
if (error1) throw error1;
});
}
val["coingrabbed"] = redeem_coin_grabbed;
final.push(val);
});
}
res.send(final);
});
Please check if this works, Using this idea https://stackoverflow.com/a/7053992/9216722
let final = [];
dbcon.query('SELECT ci_offers.*, ci_advertisers.id as merchant_id, ci_advertisers.full_name, ci_advertisers.phone, ci_advertisers.companylogo FROM ci_offers, ci_advertisers WHERE ci_offers.advertiser_id = ci_advertisers.id AND ci_offers.is_active=1', function(error, results, fields) {
if (error) throw error;
if (results.length > 0) {
var objectOffer;
var objCoin;
// async.forEachOf(results, function (dataElement, i, inner_callback){
let done = false;
let count = 0;
const markDone = (err) => {
count++;
if ( !done && results.length === count) {
done = true;
res.send(final);
}
};
results.forEach((val) => {
objectOffer = jsonParser(val);
var token_id = objectOffer.token_id;
var redeem_coin_grabbed = 0;
if (token_id > 0) {
dbcon.query('SELECT count(id) as coingrabbed FROM ci_grabcoin_details_for_game WHERE user_id = ? AND coin_id= 33', [user_id, token_id], function(error1, results1, fields1) {
if (error1) throw error1;
});
}
val["coingrabbed"] = redeem_coin_grabbed;
final.push(val);
markDone();
});
}
});

Upload Excel using nodejs

I am uploading an Excel file and inserting into a mysql table. My code is working with Linux. But I want it should run with other also so I am predicting that Xls is not working.
How to change into CSV or any other way so we can upload the Excel or csv which support any version?
function getfileDetails(req, res) {
var sampleFile, fileInfo = {};
var date1=new Date();
var currdatetime = date1.getFullYear()+"-"+(date1.getMonth()+1)+"-"+date1.getDate()+" "+date1.getHours()+":"+date1.getMinutes()+":"+date1.getSeconds();
console.log(currdatetime);
var MyData = [];
if (!req.files) {
res.send('No files were uploaded.');
return;
}
sampleFile = req.files.fileInputXLSX1;
var datetimestamp = Date.now();
console.log("Uploaded -- ",sampleFile);
var fileExtn = sampleFile.name.split(".").pop();
var extractedFilename = sampleFile.name.slice(0, sampleFile.name.lastIndexOf('.'));
var userid=req.headers['userid'];
var uploadFileName = extractedFilename+'_'+userid+'_'+datetimestamp+'.'+fileExtn;
console.log("uploadFileName -- ",uploadFileName);
fileInfo = {
"name": uploadFileName,
"mimetype": sampleFile.mimetype
}
// Use the mv() method to place the file somewhere on your server
sampleFile.mv(__dirname+'/Details/'+uploadFileName, function(err) {
if (err) {
res.status(500).send(err);
}
var parseXlsx = require('excel');
parseXlsx(__dirname+'/Details/'+uploadFileName, function(err, data) {
if(err) throw err;
// data is an array of arrays
else{
if(data!=null)
{
var queryString= "Truncate table `details`;"
connection.query(queryString, function(err,result){
if(err) {
res.write(JSON.stringify(err));
res.end();
} else {
res.send('File uploaded!');
}
});
}
for (var index = 1; index < data.length; index++)
{
MyData.push(data[index][0],data[index][1],data[index][2],data[index][3], data[index][4], data[index][5],data[index][6],data[index][7],data[index][8],data[index][9]);
var queryString="INSERT INTO `details`(name,tname,fname,timestamp) VALUES ('"+data[index][0]+"','"+data[index][1]+"','"+data[index][2]+"','"+currdatetime+"')";
connection.query(queryString, function(err,result){
if(err) {
res.write(JSON.stringify(err));
res.end();
} else {
res.send('File uploaded!');
}
});
}
}
});
if(err) {
res.status(500);
res.send(err);
}
});
}
Please help ,I am New in Node.
hey can you try json2csv npm module. this will solve you problem #TB.M
This code is working fine, try this..
var xlsx = require('node-xlsx');
var fs = require('fs');
var obj = xlsx.parse(__dirname + '/new.xls'); // parses a file
var rows = [];
var writeStr = "";
//looping through all datarow
for(var i = 0; i < obj.length; i++)
{
var dataRow = obj[i];
//loop through all rows in the sheet
for(var j = 0; j < dataRow['data'].length; j++)
{
//add the row to the rows array
rows.push(dataRow['data'][j]);
}
}
//creates the csv string to write it to a file
for(var i = 0; i < rows.length; i++)
{
writeStr = writeStr + rows[i].join(",") + "\n";
}
//writes to a file, but you will presumably send the csv as a
//response instead
fs.writeFile(__dirname + "/data.csv", writeStr, function(err) {
if(err) {
return console.log(err);
}
console.log("data.csv was saved in the current directory!");
});

Return boolean value from MYSQL in NodeJS

Im working on a function which will return a boolean-value. This value represents if an user exists in the database. Currently I have this:
function checkIfExists(){
var sql = "SELECT * FROM Users WHERE user = " + mysql.escape(req.body.username);
var rows = 0;
database.query(sql, function(err, result, fields){
console.log(result.length);
rows += result.length;
});
return rows > 0;
}
console.log(checkIfExists());
I use 'console.log(result.length)' to validate if there are results. When I test some input, I got this:
false
1
This is strange because there is one result, so rows should be equal to 1. But then it returns false instead of true. Is it possible that the value of rows isn't changed in 'database.query(...' ?
Because your function checkIfExists is asynchronous, I think you sould use callback system like this :
function checkIfExists(callback) {
var sql = "SELECT * FROM Users WHERE user = " + mysql.escape(req.body.username);
var rows = 0;
database.query(sql, function (err, result, fields) {
if (err) {
callback(err, null);
}
else {
console.log(result.length);
rows += result.length;
callback(null, rows > 0);
}
});
}
checkIfExists(function(err, isExists) {
if (err) {
// An error occured
}
else {
console.log(isExists);
}
});
EDIT
You also can simlify your checkIfExists function like this :
function checkIfExists(callback) {
var sql = "SELECT * FROM Users WHERE user = " + mysql.escape(req.body.username);
database.query(sql, function (err, result) {
callback(err, result ? result.length > 0 : false);
});
}
More information here :
Understanding Async Programming in Node.js
Hope it helps.

How to handle nodejs async with mysql?

Community,
I am new at nodejs and now i have a problem i cant solve: The async in javascript/nodejs. How can i handle the following so i can push the usernames to the array?
I already tried to help myself with many different functions but nothing works for me... :/
Sincerely Adhskid.
function getCurrentBetInformations () {
connection.query('SELECT * FROM `BETS` WHERE BET_ACTIVE = "1" LIMIT 1', function(err, rowss, fields) {
if (err) logger.warn('MySQL Error: ' + err.stack);
betid = rowss[0].BET_ID;
betends = rowss[0].BET_END;
connection.query('SELECT * FROM `BETS_BID` WHERE BID_BET_ID=\'' + betid + '\'', function(err, betbids, fields) {
if (err) logger.warn('MySQL Error: ' + err.stack);
var betQuants = new Array();
var betIds = new Array();
var betUsernames = new Array();
var betDates = new Array();
var rowsAffected = betbids.length;
for(i=0; i < rowsAffected; i++) {
betQuants.push(betbids[i].BID_KEYS_COUNT);
betIds.push(betbids[i].BID_ID);
var betSender = betbids[i].BID_SENDER;
connection.query('SELECT `USER_NAME` FROM `USER` WHERE `USER_STEAMID` = \'' + betSender + '\' LIMIT 1', function(err, rows, fields) {
if (err) logger.warn('MySQL Error: ' + err.stack);
console.log(rows[0].USER_NAME);
addUsername(rows[0].USER_NAME);
});
function addUsername (currentUsername) {
betUsernames.push(currentUsername);
}
betDates.push(betbids[i].BID_TIME);
if(betUsernames.length === i) {
execSiteRef();
}
}
function execSiteRef() {
console.log(betUsernames);
sendUserSiteRefresh([betQuants, betIds, betUsernames, betDates], betends);
}
});
});
}
I think your problem comes from this part:
if(betUsernames.length === i) {
execSiteRef();
}
You should iinstead check if the betUsernames array is of the final size:
if(betUsernames.length === rowsAffected) {
execSiteRef();
}
maybe there is more errors though, I did not check closely.