Array push gives empty result node js - node.js

I am creating an API for listing trip data with image and pdf base url,
All things are working fine but I can not access the last result array data_to_send out of for loop.
app.js
app.get("/getChallanList/:userId/:role", (req, res) => {
const userData = req.params;
let site_source = "";
let site_destination = "";
var site_from_name = "";
const data_to_send = [];
if (userData.role == "D") {
db.select("trip", "*", `driver_id = '${req.params.userId}'`, (data) => {
for (let i = 0; i < data.data.length; i++) {
site_source = data.data[i].site_from;
site_destination = data.data[i].site_to;
db.select(
"site",
"*",
`id in ('${site_source}','${site_destination}')`,
(data_site) => {
data.data[i].site_from = data_site.data[0].name;
data.data[i].site_to = data_site.data[1].name;
if (data.data[i].truck_challan_pdf != "") {
data.data[i].truck_challan_pdf =
base_url + "truckchallan/" + data.data[i].truck_challan_pdf;
}
if (data.data[i].driver_challan_pdf != "") {
data.data[i].driver_challan_pdf =
base_url + "driverchallan/" + data.data[i].driver_challan_pdf;
}
if (data.data[i].preparer_img != "") {
data.data[i].preparer_img = base_url + data.data[i].preparer_img;
}
if (data.data[i].driver_img != "") {
data.data[i].driver_img = base_url + data.data[i].driver_img;
}
data_to_send.push(data.data);
// console.log(data_to_send); // working
}
);
}
console.log(data_to_send); // empty
});
}
}
db.select
let select = (table, column, condition, callback) => {
try {
let sql = "SELECT " + column + " FROM " + table + " WHERE " + condition;
conn.query(sql, (err, results) => {
if (err) {
let data = {
status: 0,
data: sql,
message: "Something went wrong!",
};
callback(data);
} else {
let data = {
status: 1,
data: results,
message: "Success",
};
callback(data);
}
});
} catch (err) {
let data = {
status: 0,
data: err,
message: "In catch",
};
callback(data);
}
};
async await
app.get("/getChallanList/:userId/:role", async (req, res) => {
const userData = req.params;
let site_source = "";
let site_destination = "";
var site_from_name = "";
const data_to_send = [];
if (userData.role == "D") {
await db.select(
"trip",
"*",
`driver_id = '${req.params.userId}'`,
async (data) => {
// const data_to_send_ = [];
for (let i = 0; i < data.data.length; i++) {
site_source = data.data[i].site_from;
site_destination = data.data[i].site_to;
await db.select(
"site",
"*",
`id in ('${site_source}','${site_destination}')`,
(data_site) => {
data.data[i].site_from = data_site.data[0].name;
data.data[i].site_to = data_site.data[1].name;
if (data.data[i].truck_challan_pdf != "") {
data.data[i].truck_challan_pdf =
base_url + "truckchallan/" + data.data[i].truck_challan_pdf;
}
if (data.data[i].driver_challan_pdf != "") {
data.data[i].driver_challan_pdf =
base_url + "driverchallan/" + data.data[i].driver_challan_pdf;
}
if (data.data[i].preparer_img != "") {
data.data[i].preparer_img =
base_url + data.data[i].preparer_img;
}
if (data.data[i].driver_img != "") {
data.data[i].driver_img = base_url + data.data[i].driver_img;
}
data_to_send.push(data.data);
// console.log(data_to_send); // working
}
);
// data_to_send_.push(data_to_send);
}
console.log(data_to_send); // empty
}
);
}
}

this is because of the asynchronous behavior of NodeJs, so you have to plan things accordingly i.e
console.log(1)
db.select(
"trip",
"*",
`driver_id = '${req.params.userId}'`,
async (data) => {
console.log(2)
})
console.log(3)
The output of the above code would be 1 then 3 and then 2 and this is how NodeJs works it does not wait for I/O calls i.e DB query in your case.
Please check how promises work in NodeJs for more details.
Here is how you can accomplish your task:
const challanList = (userData) => {
return new Promise((resolve, reject) => {
const data_to_send = [];
db.select("trip", "*", `driver_id = '${req.params.userId}'`, data => {
for (let i = 0; i < data.data.length; i++) {
const site_source = data.data[i].site_from;
const site_destination = data.data[i].site_to;
db.select("site", "*", `id in ('${site_source}','${site_destination}')`, data_site => {
data.data[i].site_from = data_site.data[0].name;
data.data[i].site_to = data_site.data[1].name;
if (data.data[i].truck_challan_pdf != "") {
data.data[i].truck_challan_pdf = base_url + "truckchallan/" + data.data[i].truck_challan_pdf;
}
if (data.data[i].driver_challan_pdf != "") {
data.data[i].driver_challan_pdf = base_url + "driverchallan/" + data.data[i].driver_challan_pdf;
}
if (data.data[i].preparer_img != "") {
data.data[i].preparer_img = base_url + data.data[i].preparer_img;
}
if (data.data[i].driver_img != "") {
data.data[i].driver_img = base_url + data.data[i].driver_img;
}
data_to_send.push(data.data);
// console.log(data_to_send); // working
});
}
resolve(data_to_send);
});
});
};
app.get("/getChallanList/:userId/:role", async (req, res) => {
const userData = req.params;
const challanListResult =await challanList(userData);
console.log(challanListResult);
resp.json(challanListResult);
});

Without knowing what database or ORM you are using it is difficult to answer, but my suspicion is that db.select is an asynchronous method, i.e. it is returning a Promise. If so, the second console log is still seeing the "old" data_to_send.
Try adding an await in front of the first db.select call. (Don't forget the async in front of the callback in second argument of app.get.

Your database is asynchronous so console.log(data_to_send) gets called before the query finished executing. Try adding async before (req, res) in line 1 then await before db.select.

This works for me
app.get("/getChallanList/:userId/:role", async (req, res) => {
const userData = req.params;
let site_source = "";
let site_destination = "";
var site_from_name = "";
const data_to_send = [];
if (userData.role == "D") {
const data = await db.query(
`SELECT * FROM trip WHERE driver_id = '${req.params.userId}'`
);
// console.log(data.length);
// const data_to_send_ = [];
for (let i = 0; i < data.length; i++) {
site_source = data[i].site_from;
site_destination = data[i].site_to;
// cons
const site_data = await db.query(
`SELECT * FROM site WHERE id in ('${site_source}','${site_destination}')`
);
// console.log(site_data);
db.select(
"site",
"*",
`id in ('${site_source}','${site_destination}')`,
(data_site) => {
data[i].site_from = data_site.data[0].name;
data[i].site_to = data_site.data[1].name;
if (data[i].truck_challan_pdf != "") {
data[i].truck_challan_pdf =
base_url + "truckchallan/" + data[i].truck_challan_pdf;
}
if (data[i].driver_challan_pdf != "") {
data[i].driver_challan_pdf =
base_url + "driverchallan/" + data[i].driver_challan_pdf;
}
if (data[i].preparer_img != "") {
data[i].preparer_img = base_url + data[i].preparer_img;
}
if (data[i].driver_img != "") {
data[i].driver_img = base_url + data[i].driver_img;
}
data_to_send.push(data);
// console.log(data.data);
// console.log(data_to_send); // working
}
);
// data_to_send_.push(data_to_send);
}
// console.log(data_to_send);
// console.log(data_to_send);
res.send({ success: 1, data: data, message: "" });
}

Related

Column values swapping while passing tvp to sql procedure from node js

I am facing a challenge that when I call a procedure and pass a table value parameter to it from Node.JS . 2 particular Columns values are swapped when read by Stored Procedure. Below is my API end point code
const sql = require("mssql/msnodesqlv8");
const dataAccess = require("../DataAccess");
const fn_CreateProd = async function (product) {
let errmsg = "";
let objBlankTableStru = {};
let connPool = null;
await sql
.connect(global.config)
.then((pool) => {
global.connPool = pool;
productsStru = pool.request().query("select * from products where 1=2");
return productsStru;
})
.then(productsStru=>{
objBlankTableStru.products = productsStru
productsOhStru = global.connPool.request().query("select * from products_oh where 1=2");
return productsOhStru
})
.then((productsOhStru) => {
objBlankTableStru.products_oh = productsOhStru
let objTvpArr = [
{
uploadTableStru: objBlankTableStru,
},
{
tableName : "products",
tvpName: "tvp_products",
tvpPara: "tblProds"
},
{
tableName : "products_oh",
tvpName: "tvp_product_oh",
tvpPara: "tblProdsOh",
}
];
newResult = dataAccess.getPostResult(
objTvpArr,
"sp3s_ins_products_tvp",
product
);
console.log("Result of Execute Final procedure", newResult);
return newResult;
})
.then((result) => {
// console.log("Result of proc", result);
if (!result.recordset[0].errmsg)
errmsg = "Products Inserted successfully";
else errmsg = result.recordset[0].errmsg;
})
.catch((err) => {
console.log("Enter catch of Posting prod", err.message);
errmsg = err.message;
if (errmsg == "") {
errmsg = "Unknown error from Server... ";
}
})
.finally((resp) => {
sql.close();
});
return { retStatus: errmsg };
};
module.exports = fn_CreateProd;
Below is the reference code of Function Getpostresult
const getPostResult = (tvpNamesArr, procName, sourceData,singleTableData) => {
let arrtvpNamesPara = [];
let prdTable = null;
let newSrcData = [];
let uploadTable = tvpNamesArr[0];
for (i = 1; i <= tvpNamesArr.length - 1; i++) {
let tvpName = tvpNamesArr[i].tvpName;
let tvpNamePara = tvpNamesArr[i].tvpPara;
let TableName = tvpNamesArr[i].tableName
let srcTable = uploadTable.uploadTableStru[TableName]
srcTable = srcTable.recordset.toTable(tvpName);
let newsrcTable = Array.from(srcTable.columns);
newsrcTable = newsrcTable.map((i) => {
i.name = i.name.toUpperCase();
return i;
});
if (!singleTableData)
newSrcData = sourceData.filter(obj=>{
return (obj.tablename.toUpperCase()===TableName.toUpperCase())
})
else
{
newSrcData = sourceData
}
console.log(`Filtered Source data for Table:${TableName}`,newSrcData)
prdTable = generateTable(newsrcTable, newSrcData, tvpName);
arrtvpNamesPara.push({ name: tvpNamePara, value: prdTable });
}
const newResult = execute(procName, arrtvpNamesPara);
return newResult;
};

Code runs before request is completed on NodeJS

I have the following code: (the code runs without issues)
function getValoresAcao(acoes) {
acoes.forEach(acao => {
getValorAcao(acao)
});
console.log("the end")
}
function getValorAcao(acao) {
url = 'https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&parse_mode=HTML&symbol='+acao+'&apikey='+API_KEY
request(url, { json: true }, (err, res, body) => {
if (err) { return console.log(err); }
let contador = 0;
let valorDeDoisDias = [];
const dailyJsonObject = body["Time Series (Daily)"]
var objectKeysArray = Object.keys(dailyJsonObject)
objectKeysArray.forEach(function(objKey) {
var objValue = dailyJsonObject[objKey]
if (contador < NUMERO_DE_ELEMENTOS )
{
//console.log(dailyJsonObject);
const valorFechamento = objValue["4. close"]
console.log(valorFechamento);
contador = contador + 1
valorDeDoisDias.push(valorFechamento);
}
});
const textoDiferenca = getDiferencaEmPorcentagem(valorDeDoisDias);
let bigString = "" + acao + " | " + valorDeDoisDias[0] + " | " + textoDiferenca
request(urlTelegram + bigString, { json: true }, (err, res, bodyTelegram) => {
console.log(bodyTelegram);
})
});
}
function getDiferencaEmPorcentagem(valprDeDoisDias) {
let myString = ""
const valorDiaAnterior = valprDeDoisDias[0]
const valorDiaMaisRecente = valprDeDoisDias[1]
myString = (valorDiaAnterior - valorDiaMaisRecente ) / valorDiaMaisRecente * 100
myString = myString.toFixed(2)
console.log(myString)
return myString + "%"
}
But the code console.log("the end") is supposed to run after the request is completed, but it runs when I start the code, it didn't wait the request to be finished.
How can I make the "the end" part of the code wait the request be executed?
probably something like that could help:
async function getValoresAcao(acoes) {
await Promise.all(acoes.map(getValorAcao))
console.log("the end")
}
async function getValorAcao(acao) {
const url = 'https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&parse_mode=HTML&symbol=' + acao + '&apikey=' + API_KEY
return new Promise ((resolve, reject)=>{
try{
request(url, { json: true }, (err, res, body) => {
if (err) {
throw err
}
let contador = 0;
let valorDeDoisDias = [];
const dailyJsonObject = body["Time Series (Daily)"]
var objectKeysArray = Object.keys(dailyJsonObject)
objectKeysArray.forEach(function (objKey) {
var objValue = dailyJsonObject[objKey]
if (contador < NUMERO_DE_ELEMENTOS) {
//console.log(dailyJsonObject);
const valorFechamento = objValue["4. close"]
console.log(valorFechamento);
contador = contador + 1
valorDeDoisDias.push(valorFechamento);
}
});
const textoDiferenca = getDiferencaEmPorcentagem(valorDeDoisDias);
let bigString = "" + acao + " | " + valorDeDoisDias[0] + " | " + textoDiferenca
request(urlTelegram + bigString, { json: true }, (err, res, bodyTelegram) => {
if(err){
throw err
}
resolve(bodyTelegram)
})
});
} catch (e) {
reject(e)
}
})
}
function getDiferencaEmPorcentagem(valprDeDoisDias) {
let myString = ""
const valorDiaAnterior = valprDeDoisDias[0]
const valorDiaMaisRecente = valprDeDoisDias[1]
myString = (valorDiaAnterior - valorDiaMaisRecente) / valorDiaMaisRecente * 100
myString = myString.toFixed(2)
console.log(myString)
return myString + "%"
}

Struggling to use async await within for loops with nodejs

I am trying to use multiple functions within a for loop but, one is returning undefined (or not waiting?)
Code is as below:
var arrNew = [];
var id = [];
var get1 = [];
var get2 = [];
var get3 = [];
var res = [];
var get4 = [];
for (j = 0; j < arrNew.length; j++) {
id[j] = arrNew[j];
get1[j] = await get1Fun(context, id[j]);
if (get1[j] !== false) {
get2[j] = await get2Fun(context, get1[j]);
context.log(get2[j]);
if (get2[j].length) {
get3[j] = await get3Fun(context, get2[j]);
if (get3[j] !== false && get3[j].status == 200) {
res[j] = get3[j].result;
get4[j] = await get4Fun(context, id[j], res[j]);
context.log(get4[j])
}
}
}
}
async function get1Fun(context, id) {
const querySpec = {
query: `SELECT * FROM r where r.id = "${id}"`,
};
const { resources } = await client.database(databaseId).container(containerId).items.query(querySpec).fetchAll();
if (resources.length == 1) {
return resources[0];
} else if (!resources.length) {
return false;
}
}
function get2Fun(context, getInt) {
return new Promise((resolve, reject) => {
var msg = []
// do for loop stuff with getInt and push stuff into msg
context.log(msg)
resolve(msg);
});
}
The code works up until this point where get2Fun either returns undefined or if (get2[j].length) does not wait for await get2Fun.
Can someone clarify what is going wrong please?
I have tried with async function and without the promise.
The reason I have the arrays as below is because if I structured the function as var get1 = await get1Fun(context, id) then the for loop would stop after 1 or 2 items and not do every item in arrNew.
Thanks in advance.
EDIT:
Also tried the below but the for loop stops after 1 loop (presumably an issue with each loop redefining a variable?):
for (j = 0; j < arrNew.length; j++) {
var id = arrNew[j];
var get1 = await get1Fun(context, id);
if (get1 !== false) {
var get2 = await get2Fun(context, get1);
context.log(get2);
if (get2.length) {
var get3 = await get3Fun(context, get2);
if (get3 !== false && get3.status == 200) {
var res = get3.result;
var get4 = await get4Fun(context, id, res);
context.log(get4)
}
}
}
}
async function get1Fun(context, id) {
const querySpec = {
query: `SELECT * FROM r where r.id = "${id}"`,
};
const { resources } = await client.database(databaseId).container(containerId).items.query(querySpec).fetchAll();
if (resources.length == 1) {
return resources[0];
} else if (!resources.length) {
return false;
}
}
async function get2Fun(context, getInt) {
var msg = []
// do for loop stuff with getInt and push stuff into msg
context.log(msg)
return msg;
}

How can write a column in tsv file using node js?

I have to write a json response in a column of tsv file how can I do that?
I am using the following code. Please find me a solution? I have to check it but its not working.
//npm init -y gen package.json file
var unProcessedItems = [];
var data = loadData('./Alabama_Pre_Final.tsv');
async function X(i) {
if (data[i] && data[i][7]) {
console.log(data[i][7]);
function address(address_details) {
request({
url: 'https://us-extract.api.smartystreets.com/?auth-id=xxx&auth-token=xxx',
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: address_details,
},
(error, response, body) => {
if (!error && response.statusCode == 200) {
var res = JSON.parse(body);
let objectArray = [];
if (res.addresses[0].verified) {
objectArray.push(res.addresses[0].api_output[0].delivery_line_1, res.addresses[0].api_output[0].last_line, res.addresses[0].api_output[0].delivery_point_barcode)
}
var address_data = objectArray.join([separator = ','])
console.log(address_data)
}
});
}
address("1000 Greenhill Blvd NW, Fort Payne, 35967, AL, USA");
const data = 'Column 19\n1\t2\t3\n4\t5\t6';
require('fs').writeFileSync('./Alabama_Pre_Final.tsv', data);
// i++;
// X(i);
}
}
}
I've looked at your answer above I think it should be easy enough to modify so that it works as you expect, I've done this below. The other functions should be left unchanged. So the function X processes each row then returns a record variable which we append to the records array. After processing is complete we write the records array to the csv file.
async function loadData(filePath) {
if (fs.existsSync(filePath)) {
var tsvData = fs.readFileSync(filePath, 'utf-8');
var rowCount = 0;
var scenarios = [];
parse_tsv(tsvData, (row) => {
rowCount++;
if (rowCount > 1) {
scenarios.push(row);
}
});
return scenarios;
} else {
console.log("loadData: Returning empty..")
return [];
}
}
// Process a row of TSV data
function X(row) {
return new Promise((resolve, reject) => {
if (row && row[7]) {
console.log(row[7]);
request({
url: 'https://us-extract.api.smartystreets.com/?auth-id=e62698e8-c3fc-b929-0f5b-d3b54d0bcd0c&auth-token=cibfMexBdl3HrmwbWY6p',
method: 'POST',
headers: { 'content-type': 'application/json' },
body: row[7],
},
(error, response, body) => {
if (!error && response.statusCode == 200) {
var res = JSON.parse(body);
let objectArray = [];
if (res.addresses[0].verified) {
objectArray.push(res.addresses[0].api_output[0].delivery_line_1, res.addresses[0].api_output[0].components.city_name,
res.addresses[0].api_output[0].components.zipcode, res.addresses[0].api_output[0].components.state_abbreviation)
}
var address_data = objectArray.join([separator = ','])
resolve({ name: address_data.replace(/['"]+/g, '') });
} else if (error) {
reject(error);
} else {
reject( { statusCode: response.statusCode });
}
});
}
});
}
async function processData() {
let MAX_RECORDS = 5; // Change as appropriate
var data = await loadData('./Alabama_Pre_Final.tsv');
if (data.length > 0) {
unProcessedItems = [];
let records = [];
for(let row of data) {
// Process a row of data.
let record = await X(row);
records.push(record);
if (records.length === MAX_RECORDS) break;
}
console.log(records);
csvWriter.writeRecords(records)
.then(() => console.log('The CSV file was written successfully'));
} else {
console.log("No Data");
}
}
processData();
const fs = require('fs');
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
var rp = require('request-promise');
var dataToWrite;
var http = require("http");
var request = require('request');
function loadData(filePath) {
if (fs.existsSync(filePath)) {
var tsvData = fs.readFileSync(filePath, 'utf-8');
var rowCount = 0;
var scenarios = [];
parse_tsv(tsvData, (row) => {
rowCount++;
if (rowCount > 1) {
scenarios.push(row);
}
});
return scenarios;
} else {
return [];
}
}
function parse_tsv(s, f) {
var ix_end = 0;
for (var ix = 0; ix < s.length; ix = ix_end + 1) {
ix_end = s.indexOf('\n', ix);
if (ix_end == -1) {
ix_end = s.length;
}
//var row = s.substring(ix, ix_end - 1).split('\t');
var row = s.substring(ix, ix_end).split('\t');
f(row);
}
}
var unProcessedItems = [];
var data = loadData('./Alabama_Pre_Final.tsv');
var records = [];
async function X(i) {
if (data[i] && data[i][7]) {
console.log(data[i][7]);
var options = {
method: 'POST',
url: 'https://us-extract.api.smartystreets.com/?auth-id=c64de073-9531-9444-35e6-7204d9d62c36&auth-token=e5FxYc1niUD7Cp0peixd',
headers: {
'content-type': 'application/json'
},
body: data[i][7],
json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(function (parsedBody) {
// POST succeeded...
var res = parsedBody;
let objectArray = [];
if (res.addresses.length) {
if (res.addresses[0].verified) {
objectArray.push(res.addresses[0].api_output[0].delivery_line_1, res.addresses[0].api_output[0].components.city_name,
res.addresses[0].api_output[0].components.zipcode, res.addresses[0].api_output[0].components.state_abbreviation)
}
var address_data = objectArray.join([separator = ','])
console.log(address_data)
// records.push({ name: address_data.replace(/['"]+/g, '') });
const ADDRESS_COLUMN_INDEX = 7;
for(let row of address_data) {
row[ADDRESS_COLUMN_INDEX] = await X(row[ADDRESS_COLUMN_INDEX]);
}
records.push(address_data.replace(/['"]+/g, ''));
let output = records.map(row => row.join("\t")).join("\n");
i++;
if (i <= 7) {
X(i);
}
else {
fs.writeFileSync('out.tsv', output);
console.log('The TSV file was written successfully');
// return callback(records);
}
}
});
}
// console.log(records);
}
if (data.length > 0) {
unProcessedItems = [];
X(0);
} else {
console.log("No Data");
}
I've updated this answer based on your last revisions, I hope this helps you:
function loadData(filePath) {
if (fs.existsSync(filePath)) {
var tsvData = fs.readFileSync(filePath, 'utf-8');
var rowCount = 0;
var scenarios = [];
parse_tsv(tsvData, (row) => {
rowCount++;
if (rowCount > 1) {
scenarios.push(row);
}
});
return scenarios;
} else {
return [];
}
}
function parse_tsv(s, f) {
var ix_end = 0;
for (var ix = 0; ix < s.length; ix = ix_end + 1) {
ix_end = s.indexOf('\n', ix);
if (ix_end == -1) {
ix_end = s.length;
}
var row = s.substring(ix, ix_end).split('\t');
f(row);
}
}
var unProcessedItems = [];
var data = loadData('./Alabama_Pre_Final.tsv');
var records = [];
async function X(i) {
if (data[i] && data[i][7]) {
console.log(data[i][7]);
var options = {
method: 'POST',
url: 'https://us-extract.api.smartystreets.com/?auth-id=c64de073-9531-9444-35e6-7204d9d62c36&auth-token=e5FxYc1niUD7Cp0peixd',
headers: {
'content-type': 'application/json'
},
body: data[i][7],
json: true // Automatically stringifies the body to JSON
};
rp(options)
.then(async function (parsedBody) {
// POST succeeded...
var res = parsedBody;
let objectArray = [];
if (res.addresses.length) {
if (res.addresses[0].verified) {
objectArray.push(res.addresses[0].api_output[0].delivery_line_1, res.addresses[0].api_output[0].components.city_name,
res.addresses[0].api_output[0].components.zipcode, res.addresses[0].api_output[0].components.state_abbreviation)
}
var address_data = objectArray.join([separator = ','])
console.log("rp.then -> address_data:",address_data);
data[i][7] = address_data.replace(/['"]+/g, '');
records.push(data[i].join("\t"));
i++;
if (i <= 7) {
console.log("Looking up address #" + i);
X(i);
} else {
const output = records.join("\n");
// Remove the _test when you are happy with the result.
fs.writeFileSync('./Alabama_Pre_Final_test.tsv', output);
console.log('The TSV file was written successfully');
}
}
});
}
}
if (data.length > 0) {
unProcessedItems = [];
X(0);
} else {
console.log("No Data");
}

nodejs async how to set callback

I have the following piece of code which is working fine.
var config = require('./config');
var cheerio = require('cheerio');
var myhttp = require('./myHttp');
var stringHelper = require('./stringHelper');
var Base64 = require('./base64.js').Base64;
var Encrypt = require('./Encrypt.js');
var myEncode = require('./Encode.js');
var rules = require('./rules');
var io = require('socket.io-emitter')({ host: '127.0.0.1', port: 6379 });
var mysql = require('mysql');
delete require.cache[require.resolve('./requestLogin1.js')]
var myvar = require('./requestLogin1.js');
var connection = mysql.createConnection(
{
host : 'localhost',
user : 'root',
password : 'abc',
database : 'abcd'
}
);
connection.connect(function(err) {
if (err) {
console.log('error connecting: ' + err.stack);
return;
}
});
var timerOB;
var timerMW;
var timerP;
var timerTL;
var news = {
'mw': [],
'ob': [],
'all': {},
};
var status = false;
function round(rnum, rlength) {
return newnumber = Math.round(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
}
function roundup(rnum, rlength) {
return newnumber = Math.ceil(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
}
function rounddown(rnum, rlength) {
return newnumber = Math.floor(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
}
function function1(_html) {
console.log('function1 run')
var $ = cheerio.load(_html);
var v_lgnid = $('#userId').attr('value');
var v_psswrd = config.password;
var v_data = v_lgnid + "|" + v_psswrd;
var _key = $('#accntid').attr('value');
if (_key) {
v_data = Base64.encode(Encrypt.AESEncryptCtr(v_data, _key , "256"));
v_data = escape(v_data);
myhttp.get(
'https://example.com/ValidPassword.jsp?' + $('#name').attr('value') + "=" + v_data,
function (_htmlShowImage) {
if (_htmlShowImage && _htmlShowImage.trim() == "OK") {
function2();
} else {
console.log('Login Fail');
}
});
} else {
login();
console.log('Encrypt password error');
}
}
function function2() {
myhttp.get(
'https://example.com/QuestionsAuth.jsp',
function (_htmlShowImage) {
var $ = cheerio.load(_htmlShowImage);
var sLoginID = $('#sLoginID').attr('value');
var Answer1 = config.answer1;
var Answer2 = config.answer2;
var Index1 = $('#st1').attr('value');
var Index2 = $('#st2').attr('value');
var v_data = sLoginID + "|" + Answer1 + "|" + Answer2 + "|" + Index1 + "|" + Index2;
v_data = Base64.encode(Encrypt.AESEncryptCtr(v_data, $('#key_questauth').attr('value'), "256"));
v_data = escape(v_data);
myhttp.get(
'https://example.com/ValidAnswers.jsp?' + $('#name_questauth').attr('value') + "=" + v_data,
function (_htmlShowImage) {
if (_htmlShowImage && _htmlShowImage.trim() == "OK") {
//rootCallback();
myhttp.get(
'https://example.com/DefaultLogin.jsp',
function (_html) {
console.log('Login sucess')
stringHelper.SaveFileCookies('abcd.txt', myhttp.loadCookie(), 'save cookie login sucess');
if (timerMW) {
clearTimeout(timerMW);
}
timerMW = setTimeout(function6, config.DelayExtractMW);
if (timerOB) {
clearTimeout(timerOB);
}
timerOB = setTimeout(function5, config.DelayExtractOB);
if (timerP) {
clearTimeout(timerP);
}
timerP = setTimeout(function4, config.function4);
});
} else {
console.log('Login Fail - timer');
}
});
});
}
var login = function () {
if (timerMW) {
clearTimeout(timerMW);
}
if (timerOB) {
clearTimeout(timerOB);
}
if (timerP) {
clearTimeout(timerP);
}
if (timerTL) {
clearTimeout(timerTL);
}
myhttp.init();
myhttp.post(
'https://example.com/ShowImage.jsp',
{ "requiredLogin": myEncode.Convert(config.uname) },
function (_htmlpost) {
if (_htmlpost) {
function1(_htmlpost);
} else {
if (timerTL) {
clearTimeout(timerTL);
}
timerTL = setTimeout(login, config.DelayNestError);
}
});
}
exports.login = login;
function function3() {
return {
TS: '',
MWP: 0,
LTP: 0,
NQ: 0,
OBBP: '',
OBSP: '',
CurrTime: 0,
rules: {}
};
}
function function4() {
status = false;
myhttp.get('https://example.com/PB.jsp?Exchange=',
function (_html) {
if (_html && _html.length > 10) {
news.pn = {};
$ = cheerio.load(_html);
$('tr[id^="TR"]').each(function () {
status = true;
var symbol = $('td:nth-child(3)', this).text().trim();
var objob = {
'NQ': parseInt($('td:nth-child(11)', this).text().trim()),
};
var post = {
'symbol': symbol,
'nq': objob.NQ
};
connection.query('INSERT INTO NP SET ?', post, function (err,result){
if (err)
{console.log("NP sql insert error : " +symbol);}
else {
console.log("data inserted into NP Table : " +symbol);
}
});
var objstock = news.all[symbol];
if (typeof objstock!='undefined') {
objstock.NQ = objob.NQ;
news.pn[symbol] = objob;
news.all[symbol] = objstock;
if (status) {
io.emit('news', news);
}
}
else
{
console.log('symbol not found');
}
});
if (timerP) {
clearTimeout(timerP);
}
console.log('setTimer function4:' + config.DelayExtractPn);
timerP = setTimeout(function4, config.DelayExtractPn);
}
connection.query('UPDATE MASTER1 SET tbq = (SELECT sum(a.bq) FROM (select distinct symbol, bq from NP) as a)', function (err,result){
if (err)
{console.log("CQ06 skipped: ");}
else {
console.log("Step 6 - Master1 tbq data updated");
}
});
connection.query('UPDATE MASTER1 SET tsq = (SELECT sum(a.sq) FROM (select distinct symbol, sq from NP) as a)', function (err,result){
if (err)
{console.log("CQ07 skipped: ");}
else {
console.log("Step 7 - Master1 tsq data updated");
}
});
});
}
function function5() {
status = false;
myhttp.get('https://example.com/OB.jsp?Exchange=&OrderType=All',
function (_html) {
if (_html && _html.length > 10) {
$ = cheerio.load(_html);
console.log('OB - Step 2 - html loaded for parsing');
news.ob = [];
$('tr[id^="TR"]').each(function () {
var statusOrder = $('td:nth-child(20)', this).text().trim();
if (statusOrder.toLowerCase().indexOf('open') >= 0) {
status = true;
var objob = {
'symbol': $('td:nth-child(6)', this).text().trim(),
'buysell': $('td:nth-child(9)', this).text().trim(),
'ordernumber': $('input[name="Select"]', this).attr('value'),
};
var objstock = news.all[objob.symbol];
objstock.OBBP = objob.buysell == "BUY"?objob.ordernumber:"";
objstock.OBSP = objob.buysell == "SELL"?objob.ordernumber:"";
news.ob.push(objob);
}
});
if (status) {
io.emit('news', news);
}
if (timerOB) {
clearTimeout(timerOB);
}
timerOB = setTimeout(function5, config.DelayExtractOB);
}
});
}
function function6() {
myhttp.get(
'https://example.com/MW.jsp?',
function (_html) {
if (_html && _html.length > 10) {
var $ = cheerio.load(_html);
status = false;
news.mw = [];
var countCheckRule = 0;
var countCheckedRule = 0;
var tmpall = {};
$('tr[onclick]').each(function () {
status = true;
var data1 = $("input[onclick*='Apply(']", this).attr('onclick');
var arrdata1 = data1.split("','");
var stockid = arrdata1[1].split('|')[0];
var symbol = $('td:nth-child(3)', this).text().trim();
var price = parseFloat($('td:nth-child(4)', this).text().trim());
var cTime = stringHelper.getIndiaTime();
var CurrTime = cTime.toLocaleTimeString();//(will be updated every 60 seconds)
news.mw.push({
'symbol': symbol,
'price': price,
'stockid': stockid,
'CurrTime': CurrTime,
});
var objstock = news.all[symbol];
if (!objstock) {
objstock = function3();
}
if (!news.pn[symbol]) {
objstock.NQ = 0;
}
var notfoundob = true;
for (var symbolkey in news.ob) {
if (news.ob[symbolkey].symbol == symbol) {
notfoundob = false;
}
}
if (notfoundob) {
objstock.OBBP = "";
objstock.OBSP = "";
}
objstock.TS = symbol;//trade symbol
objstock.MWP = stockid;//trade id
objstock.LTP = price;
objstock.CurrTime = CurrTime;
rules.checRules(objstock, myhttp, function (rules_res) {
objstock.rules = rules_res;
tmpall[symbol] = objstock;
});
countCheckRule++;
});
rules.rule12(tmpall, function (_tmpall) {
tmpall = _tmpall;
});
news.all = tmpall;
if (!status) {
login();
console.log('MW - Step 9 - logged out');
} else {
io.emit('news', news);
if (timerMW) {
clearTimeout(timerMW);
}
timerMW = setTimeout(function6, config.DelayExtractMW);
}
} else {
if (timerMW) {
clearTimeout(timerMW);
}
timerMW = setTimeout(function6, config.DelayExtractMW);
}
});
}
Now i want to use async to ensure that function6 is run only after function4 & function5 is run.
I have tried to learn about async from various forums and have changed the code as follows:
var async = require('async'); //line added
// change made
async.parallel([
function function4(callback) {
status = false;
myhttp.get('https://example.com/PB.jsp?Exchange=',
function (_html) {
if (_html && _html.length > 10) {
news.pn = {};
$ = cheerio.load(_html);
$('tr[id^="TR"]').each(function () {
status = true;
var symbol = $('td:nth-child(3)', this).text().trim();
var objob = {
'NQ': parseInt($('td:nth-child(11)', this).text().trim()),
};
console.log('Posn - Step 3A - Found position:' + symbol);
var post = {
'symbol': symbol,
'nq': objob.NQ
};
connection.query('INSERT INTO NP SET ?', post, function (err,result){
if (err)
{console.log("NP sql insert error : " +symbol);}
else {
console.log("data inserted into NP Table : " +symbol);
}
});
var objstock = news.all[symbol];
if (typeof objstock!='undefined') {
objstock.NQ = objob.NQ;
news.pn[symbol] = objob;
news.all[symbol] = objstock;
if (status) {
io.emit('news', news);
}
}
else
{
console.log('symbol not found');
}
});
if (timerP) {
clearTimeout(timerP);
}
console.log('setTimer function4:' + config.DelayExtractPn);
timerP = setTimeout(function4, config.DelayExtractPn);
}
connection.query('UPDATE MASTER1 SET tbq = (SELECT sum(a.bq) FROM (select distinct symbol, bq from NP) as a)', function (err,result){
if (err)
{console.log("CQ06 skipped: ");}
else {
console.log("Step 6 - Master1 tbq data updated");
}
});
connection.query('UPDATE MASTER1 SET tsq = (SELECT sum(a.sq) FROM (select distinct symbol, sq from NP) as a)', function (err,result){
if (err)
{console.log("CQ07 skipped: ");}
else {
console.log("Step 7 - Master1 tsq data updated");
}
});
callback(); //line added
});
},
function function5(callback) {
status = false;
myhttp.get('https://example.com/OB.jsp?Exchange=&OrderType=All',
function (_html) {
if (_html && _html.length > 10) {
$ = cheerio.load(_html);
console.log('OB - Step 2 - html loaded for parsing');
news.ob = [];
$('tr[id^="TR"]').each(function () {
var statusOrder = $('td:nth-child(20)', this).text().trim();
if (statusOrder.toLowerCase().indexOf('open') >= 0 || statusOrder.toLowerCase().indexOf('trigger pending') >= 0) {
status = true;
var objob = {
'symbol': $('td:nth-child(6)', this).text().trim(),
'buysell': $('td:nth-child(9)', this).text().trim(),
'ordernumber': $('input[name="Select"]', this).attr('value'),
};
var objstock = news.all[objob.symbol];
objstock.OBBP = objob.buysell == "BUY"?objob.ordernumber:"";
objstock.OBSP = objob.buysell == "SELL"?objob.ordernumber:"";
news.ob.push(objob);
}
});
if (status) {
console.log('OB - Step 5 - pushed to html page');
io.emit('news', news);
}
if (timerOB) {
clearTimeout(timerOB);
}
timerOB = setTimeout(function5, config.DelayExtractOB);
}
callback(); //line added
});
}
],
function function6() {
myhttp.get(
'https://example.com/MW.jsp?',
function (_html) {
if (_html && _html.length > 10) {
var $ = cheerio.load(_html);
status = false;
news.mw = [];
var countCheckRule = 0;
var countCheckedRule = 0;
var tmpall = {};
$('tr[onclick]').each(function () {
status = true;
var data1 = $("input[onclick*='Apply(']", this).attr('onclick');
var arrdata1 = data1.split("','");
var stockid = arrdata1[1].split('|')[0];
var symbol = $('td:nth-child(3)', this).text().trim();
var price = parseFloat($('td:nth-child(4)', this).text().trim());
var cTime = stringHelper.getIndiaTime();
var CurrTime = cTime.toLocaleTimeString();//(will be updated every 60 seconds)
news.mw.push({
'symbol': symbol,
'price': price,
'stockid': stockid,
'CurrTime': CurrTime,
});
var objstock = news.all[symbol];
if (!objstock) {
objstock = function3();
}
if (!news.pn[symbol]) {
objstock.NQ = 0;
}
var notfoundob = true;
for (var symbolkey in news.ob) {
if (news.ob[symbolkey].symbol == symbol) {
notfoundob = false;
}
}
if (notfoundob) {
objstock.OBBP = "";
objstock.OBSP = "";
}
objstock.TS = symbol;//trade symbol
objstock.MWP = stockid;//trade id
objstock.LTP = price;
objstock.CurrTime = CurrTime;
rules.checRules(objstock, myhttp, function (rules_res) {
objstock.rules = rules_res;
tmpall[symbol] = objstock;
});
countCheckRule++;
});
//new check rules
rules.rule12(tmpall, function (_tmpall) {
tmpall = _tmpall;
});
news.all = tmpall;
if (!status) {
login();
} else {
io.emit('news', news);
if (timerMW) {
clearTimeout(timerMW);
}
timerMW = setTimeout(function6, config.DelayExtractMW);
}
} else {
if (timerMW) {
clearTimeout(timerMW);
}
timerMW = setTimeout(function6, config.DelayExtractMW);
}
});
});
Since my original functions do not have any callback, and since async needs callback, i have tried to code a callback in function4 & function5 - but I guess i have not coded it correctly.
I am getting an error in the line where callback is present that states "TypeError: undefined is not a function".
How do i correct this?
Related Question No. 2 : the current code has a timer function whereby function4, function5 and function6 runs with a preset timer. If async works, how do i define a timer whereby the combined set of function4,5 & 6 works based on a preset timer?
Sorry about the long code -- i am new to nodejs and was handed over this code as such and am trying to get this change made.
Thanks for your guidance.
You can instead make function4 and function5 to return promise and then execute function6 only after both function4's and function5's promise gets resolved.

Resources