Node.JS Page only loads about 50% of the time - javascript

I have a function called parsedata in my node.js file which is called when a user logs in. After parsedata() is called, the server switches to a new screen. However, this only works every other time. I put an asynchronous wait in between, which made it work about 90% of the time but I am just wondering why it is doing this. I believe it has something to do with all of the helper functions which are being used but I am not completely sure. Any info or help would be greatly appreciated!
app.post("/login.html", urlencodedParser, async (req, res) => {
await parseData();
//await sleep(750);
res.redirect(__dirname + "/homescreen.html");
});
async function parseData() {
let dates = await findCommon();
let maxStreak = await getMaxStreak(dates);
}
async function findCommon() {
var dates = new Set();
var data = await fs.readFile(__dirname + "/mem.txt", "utf8", (err, data) => {
if (err) {
console.error(err);
return;
}
return data;
});
for (let i = 0; i < data.length; i++) {
if (data[i] === "*" && i + mostRecentName.length < data.length) {
if (data.slice(i + 1, i + mostRecentName.length + 1) == mostRecentName) {
while (data[i] != "\n") {
i++;
}
if (i < data.length - 1) {
i++;
}
while (data[i] != "*" && i < data.length) {
let curr = "";
let count = 10;
while (count > 0) {
count--;
curr += data[i];
i++;
}
while (data[i] != "\n") {
i += 1;
}
if (i < data.length - 1) {
i++;
}
dates.add(curr);
}
}
}
}
dates = Array.from(dates);
dates = await bubbleSort(dates);
return dates;
}
async function getMaxStreak(dates) {
let today = new Date();
let year = today.getFullYear().toString();
let month = (today.getMonth() + 1).toString();
let day = today.getDate().toString();
if (month.length == 1) {
month = "0" + month;
}
if (day.length == 1) {
day = "0" + day;
}
let testDate = year + "-" + month + "-"+ day;
if (!(testDate in dates)) {
dates.push(testDate);
}
let streak = 1;
for (let i = dates.length - 1; i > 0; i--) {
let options;
if (i == dates.length - 1) {
options = await convert(testDate);
} else {
options = await convert(dates[i]);
}
if (dates[i - 1] == options[0] || dates[i - 1] == options[1] || dates[i - 1] == options[2]) {
streak++;
} else {
return streak;
}
}
return streak;
}
async function convert(date) {
let option1Day = (parseInt(date.slice(8, 10)) - 1).toString();
if (option1Day.length == 1) {
option1Day = "0" + option1Day;
}
let option2Month = (parseInt(date.slice(5, 7)) - 1).toString();
if (option2Month.length == 1) {
option2Month = "0" + option2Month;
}
let option2Day = "30";
let option3Day = "31";
let option1 = date.slice(0, 8) + option1Day;
let option2 = date.slice(0, 5) + option2Month + "-" + option2Day;
let option3 = date.slice(0, 5) + option2Month + "-" + option3Day;
return [option1, option2, option3];
}

It has something with the macro and micro tasks.Your code has the same result with the following codes:
new Promise((resolve, reject) => {
findCommon().then(dates => {
getMaxStreak(dates).then(maxStreak => {})
})
resolve()
})
.then(() => {
res.redirect(__dirname + "/homescreen.html")
})
res.redirect will be added into the micro task queue;
then, getMaxStreak will be added into the micro task queue too.
finally, we will take out the first task of the micro task queue to execute, yes, it's res.redirect, not getMaxStreak.

Related

setTimeout random time

Hello how can i change it to random time between 30-50sec?
I don't need new code or something just wanna edit this
client.on('chat', function(channel, user, message, self) {
if (user.username == 'Cortex' && message === 'sar') {
test();
}
});
function test()
{
setInterval(function() {
var spamMessage = 'KEK ';
var toSpam = 'MingLee';
for (i = 0; i < 30; i++) {
spamMessage += toSpam + ' ';
}
client.say(channel, spamMessage)
}, 30000);
}
Something like this ?
client.on('chat', function(channel, user, message, self) {
if (user.username == 'Cortex' && message === 'sar') {
test();
}
});
function test()
{
const min = 30000;
const max = 50000;
const time = Math.floor(Math.random() * (max - min)) + min;
setInterval(function() {
var spamMessage = 'KEK ';
var toSpam = 'MingLee';
for (i = 0; i < 30; i++) {
spamMessage += toSpam + ' ';
}
client.say(channel, spamMessage)
}, time);
}

How to call Asyn function in another async function

How can I convert the below function into the Async function? I have to call few methods based on the outcome of the below function call once isMaxAttemptExceeded is fully executed.
let isMaxAttemptExceeded = () => {
console.log('called');
let ret = MyProfileRepository.getProfileByUserID(userEmail);
ret.then(function (response) {
//some verification here
if (userVerifiedCount >= 3) {
var curDate = moment(new Date().toISOString());
var diff = curDate.diff(nextDate, 'seconds');
if (diff > 0) {
console.log('diff - ' + diff);
setMSG(
'You have exceeded maximum allowed limit.Please try after ' +
diff / 60 +
' minutes'
);
return true;
} else {
return false;
}
} else {
return false;
}
});
};
You don’t save the then result so currently it’s useless, but if you want to return the then result it would look like this:
let isMaxAttemptExceeded = async () => {
console.log('called');
let response = await MyProfileRepository.getProfileByUserID(userEmail);
//some verification here
if (userVerifiedCount >= 3) {
var curDate = moment(new Date().toISOString());
var diff = curDate.diff(nextDate, 'seconds');
if (diff > 0) {
console.log('diff - ' + diff);
setMSG(
'You have exceeded maximum allowed limit.Please try after ' +
diff / 60 +
' minutes'
);
return true;
} else {
return false;
}
} else {
return false;
}
};
And a cleaned version:
let isMaxAttemptExceeded = async () => {
console.log('called');
let response = await MyProfileRepository.getProfileByUserID(userEmail);
//some verification here
if (userVerifiedCount < 3)
return false;
}
var curDate = moment(new Date().toISOString());
var diff = curDate.diff(nextDate, 'seconds');
if (diff <= 0) {
return false;
}
console.log('diff - ' + diff);
setMSG(`You have exceeded maximum allowed limit.Please try after ${diff / 60} minutes`);
return true;
};

Problem with asynchronous request to the database

I have a "Place your order" button that calls /orderRegistration, which in turn updates the quantity of product in stock according to the order and sends the confirmed order to the email
const orderStatus = ['Confirmed', 'Not confirmed'];
router.post('/orderRegistration', (req, res) => {
if (req.session.successAuthentication === true &&
req.session.isWorker === false) {
conn.query(`SELECT orders.id,
products.product_id,
products.product_name,
products.product_amount,
order_product.count
FROM orders INNER JOIN order_product
ON orders.id = order_product.order_id INNER JOIN products
ON order_product.product_id = products.product_id
WHERE orders.id IN(
SELECT id
FROM orders
WHERE user_id=${req.session.userId}
AND status = '${orderStatus[1]}')
AND orders.status = '${orderStatus[1]}';`, (err, selProductId) => {
if (err) {throw err;}
if (selProductId.length > 0) {
let dateNow = new Date();
let prepDate = {
day: (dateNow.getDate() < 10) ? `0${dateNow.getDate()}` : dateNow.getDate(),
month: ( dateNow.getMonth() + 1 < 10) ? `0${dateNow.getMonth() + 1}` : dateNow.getMonth() + 1,
year: dateNow.getFullYear(),
hours: (dateNow.getHours() < 10) ? `0${dateNow.getHours()}` : dateNow.getHours(),
minutes: (dateNow.getMinutes() < 10) ? `0${dateNow.getMinutes()}` : dateNow.getMinutes()
};
let orderDate = `${prepDate.day}.${prepDate.month}.${prepDate.year} ${prepDate.hours}:${prepDate.minutes}`;
let productsInOrderHTML = '';
let totalAmount = 0;
for (let i = 0; i < selProductId.length; i++) {
conn.query(`UPDATE products
SET products.product_count_stock = products.product_count_stock - ${selProductId[i].count}
WHERE products.product_id = ${selProductId[i].product_id}`, err => {
if (err) {throw err;}
productsInOrderHTML += `<tr>
<td>
${selProductId[i].product_name}
</td>
<td>
${selProductId[i].count}
</td>
<td>
${selProductId[i].product_amount}
</td>
</tr>`;
totalAmount += selProductId[i].count *
selProductId[i].product_amount;
if(i === selProductId.length - 1) {
console.log('totalAmount: ' + totalAmount);
}
});
}
} else {
res.send('error');
}
});
} else {
res.send('error');
}
});
But because the calls are asynchronous, sometimes the loop does not have time to update all the products and occurs
if(i === selProductId.length - 1) {
console.log('totalAmount: ' + totalAmount);
}
that is, sometimes totalAmount may have time to update all products, and sometimes it does not, and it turns out that totalAmount will not be equal to the cost that the user ordered the product for.
How do I rewrite the query or refactor it so that this doesn't happen again
P.S. Sorry for the English, I translated this through a translator, because I speak Russian.I may also have missed something, so correct me if necessary
The queries to the database are asynchronous which means the eventloop of nodejs will pass them to the queue and the loop will continue so you have to await for them
try this
const orderStatus = ['Confirmed', 'Not confirmed'];
router.post('/orderRegistration', async (req, res) => {
if (req.session.successAuthentication === true &&
req.session.isWorker === false) {
await conn.promise().query(`SELECT orders.id,
products.product_id,
products.product_name,
products.product_amount,
order_product.count
FROM orders INNER JOIN order_product
ON orders.id = order_product.order_id INNER JOIN products
ON order_product.product_id = products.product_id
WHERE orders.id IN(
SELECT id
FROM orders
WHERE user_id=${req.session.userId}
AND status = '${orderStatus[1]}')
AND orders.status = '${orderStatus[1]}';`, async (err, selProductId) => {
if (err) {
throw err;
}
if (selProductId.length > 0) {
let dateNow = new Date();
let prepDate = {
day: (dateNow.getDate() < 10) ? `0${dateNow.getDate()}` : dateNow.getDate(),
month: (dateNow.getMonth() + 1 < 10) ? `0${dateNow.getMonth() + 1}` : dateNow.getMonth() + 1,
year: dateNow.getFullYear(),
hours: (dateNow.getHours() < 10) ? `0${dateNow.getHours()}` : dateNow.getHours(),
minutes: (dateNow.getMinutes() < 10) ? `0${dateNow.getMinutes()}` : dateNow.getMinutes()
};
let orderDate = `${prepDate.day}.${prepDate.month}.${prepDate.year} ${prepDate.hours}:${prepDate.minutes}`;
let productsInOrderHTML = '';
let totalAmount = 0;
for (let i = 0; i < selProductId.length; i++) {
await conn.promise().query(`UPDATE products
SET products.product_count_stock = products.product_count_stock - ${selProductId[i].count}
WHERE products.product_id = ${selProductId[i].product_id}`, err => {
if (err) {
throw err;
}
productsInOrderHTML += `<tr>
<td>
${selProductId[i].product_name}
</td>
<td>
${selProductId[i].count}
</td>
<td>
${selProductId[i].product_amount}
</td>
</tr>`;
totalAmount += selProductId[i].count *
selProductId[i].product_amount;
if (i === selProductId.length - 1) {
console.log('totalAmount: ' + totalAmount);
}
});
}
} else {
res.send('error');
}
});
} else {
res.send('error');
}
});

api calls in a for loops and assign the values into a single variable to be accessible outside - nodejs

I am trying to access my API with a loop as this is one of my requirements. The code i have written is below.
currentWeekStartDate = (new Date(requestStartDate));
currentWeekEndDate = (new Date(requestEndDate));
let currentWeekStartDateNew = (new Date(requestStartDate));
let currentWeekEndDateNew = (new Date(requestEndDate));
console.log("testing ZONE");
/*test zone */
let outerEventArray = [];
while (currentWeekStartDateNew.getDate() !==currentWeekEndDateNew.getDate()){
console.log(currentWeekStartDateNew);
let startTIme = new Date(currentWeekStartDateNew);
let endTime = new Date(currentWeekEndDateNew);
startTIme.setHours(startHour,startMinute,0,0);
endTime.setHours(endHour,endMinute,0,0)
while(startTIme.getHours() !== endTime.getHours()){
let newStartTime = new Date(startTIme);
newStartTime.setHours(startTIme.getHours() + 1);
let firstTimeArg = startTIme.toISOString().replace("Z", "0000");
let secondTimeArg = newStartTime.toISOString().replace("Z", "0000");
let returnVal = getEventArray(access_token, firstTimeArg,secondTimeArg).then(res => {
return res;
});
if(returnVal !== null){
console.log("returnVal");
console.log(returnVal);
outerEventArray.push(returnVal);
console.log("returnVal");
}
/*
function
*/
startTIme = new Date(newStartTime);
}
currentWeekStartDateNew.setDate(currentWeekStartDateNew.getDate() + 1);
}
console.log("outerEventArray");
console.log(outerEventArray);
console.log("outerEventArray");
and my function for the API call is
getEventArray = async(access_token, startArguement,endArguement) => {
let eventVal;
let urlVal = "https://graph.microsoft.com/v1.0/users/" + user + "/calendarview?startdatetime=" + startArguement + "&enddatetime=" + endArguement + "";
request.get({
url: urlVal,
headers: {
"Authorization": "Bearer " + access_token
}
}, function (err, response, body) {
let bodyJSON = JSON.parse(body);
eventVal = bodyJSON.value;
if(eventVal == null){
console.log("eventVal is null");
}
else{
let eventArray = [];
for (let valueVal of Object.values(eventVal)) {
let eventStartTime = valueVal.start.dateTime;
let eventEndTime = valueVal.end.dateTime;
if (!((eventStartTime[eventStartTime.length - 1] === 'Z') || (eventStartTime[eventStartTime.length - 1] === 'z'))) {
eventStartTime = eventStartTime + "Z";
}
if (!((eventEndTime[eventEndTime.length - 1] === 'Z') || (eventEndTime[eventEndTime.length - 1]) === 'z')) {
eventEndTime = eventEndTime + "z"
}
eventArray.push({ start: new Date(eventStartTime).toLocaleString(), end: new Date(eventEndTime).toLocaleString() });
}
console.log(eventArray);
return eventArray;
}
});
}
However i am not able to get the outerEventArray value outside. My requirement is to access is outside with all the data populated. Is there any way this is possible?

Returning an array completed from an array.push inside a firebase foreach

i'm having bad time with nodejs (v6.14.0) at this moment, because i made a post request that have to do some work until return a valid response. The problem is that i get an empty array as response (if i rerun more than once the request the response will be valid), i have researched and need to manage how te promises are resolved and returned but i can't see what i need to do because i see this a bit more complex that the examples that i found, i need a more deeper advice or guide please. This is my code:
ru.post('/route', (request, response) => {
let rBody = request.body;
let weekDay = getDay(rBody.date); // Return day => "Monday"
let cRef = adminDb.database().ref('/fields/');
return cRef.orderByChild('field_size').equalTo(rBody.type).once('value').then((snap) => {
let arrResult = new Array;
snap.forEach(fields => {
infoField = fields.val();
let idFi = infoField.id_fi;
let idCen = infoField.id_cen;
let id_rsvp = idFi + "_" + rBody.date + "_" + idCen;
let id_rsvp2 = idFi + "_" + rBody.date + "_" + idCen + "_" + rBody.hour;
let resRef = adminDb.database().ref('/rsvp/' + id_rsvp + '/' + id_rsvp2);
resRef.on('value', snap => {
if (snap.val() === null) {
if (infoField.act === "true") {
let cenRef = adminDb.database().ref('/cen/' + idCen);
cenRef.on('value', snap => {
let infoCen = snap.val();
if (infoCen.act === "true") {
values = infoField.ft;
daySelected = weekDay;
dayCheck = values[daySelected];
hourSelected = rBody.hour;
hourCheck = dayCheck[hourSelected];
if (hourCheck !== "" && hourCheck !== "0") {
infoField.lat = infoCen.lat;
infoField.lon = infoCen.long;
if (rBody.lat !== undefined && rBody.long !== undefined) {
infoField.dGet = true;
} else {
infoField.dGet = false;
}
infoField.address = infoCen.address;
uRef = adminDb.database().ref('/users/');
uRef.child(rBody.userid).child('/fav/').orderByChild('id_fi').equalTo(idFi).on('value', snap => {
if (snap.exists() === true) {
infoField.fav = true
} else {
infoField.fav = false
}
arrResult.push(infoField); //how to get this arrResult (completed) to use on the next .then() on first try?
})
}
}
})
}
}
})
})
return arrResult;
}).then((res) => {
console.log("check",res);
return response.status(200).json(res); // Fist response is [], if it a new request with the same values it works...
}).catch(err => {
return response.status(err.status >= 100 && err.status < 600 ? err.code : 500).send(err.message);
})});
Resulting array must be something like this at fist try:
[{
//Values from first snapshot return (infoField) plus:
lat: infoCen.lat,
lon: infoCen.long,
dGet: true/false,
address: infoCen.address,
fav: true/false,
}]
I only get that after second running, at first one it keeps as empty []
I made some edits to your code, you are not handling promises correctly:
ru.post('/route', (request, response) => {
let rBody = request.body;
let weekDay = getDay(rBody.date); // Return day => "Monday"
let cRef = adminDb.database().ref('/fields/');
return cRef.orderByChild('field_size').equalTo(rBody.type).once('value').then((snapshot) => {
let arrResult = [];
snapshot.forEach(fields => {
let infoField = fields.val();
let idFi = infoField.id_fi;
let idCen = infoField.id_cen;
let id_rsvp = idFi + "_" + rBody.date + "_" + idCen;
let id_rsvp2 = idFi + "_" + rBody.date + "_" + idCen + "_" + rBody.hour;
let resRef = adminDb.database().ref('/rsvp/' + id_rsvp + '/' + id_rsvp2);
return resRef.on('value', snap => {
if (snap.val() === null) {
if (infoField.act === "true") {
let cenRef = adminDb.database().ref('/cen/' + idCen);
return cenRef.on('value', snap => {
let infoCen = snap.val();
if (infoCen.act === "true") {
let values = infoField.ft;
let daySelected = weekDay;
let dayCheck = values[daySelected];
let hourSelected = rBody.hour;
let hourCheck = dayCheck[hourSelected];
if (hourCheck !== "" && hourCheck !== "0") {
arrResult.push(adminDb.database().ref('/fields/' + fields.key + '/lat').set(infoCen.lat));
arrResult.push(adminDb.database().ref('/fields/' + fields.key + '/lon').set(infoCen.long));
if (rBody.lat !== undefined && rBody.long !== undefined) {
arrResult.push(adminDb.database().ref('/fields/' + fields.key + '/dGet').set(true));
} else {
arrResult.push(adminDb.database().ref('/fields/' + fields.key + '/distanciaGet').set(false));
}
arrResult.push(adminDb.database().ref('/fields/' + fields.key + '/address').set(infoCen.address));
const uRef = adminDb.database().ref('/users/');
uRef.child(rBody.userid).child('/fav/').orderByChild('id_fi').equalTo(idFi).on('value', snap => {
if (snap.exists() === true) {
arrResult.push(adminDb.database().ref('/fields/' + fields.key + '/fav').set(true));
} else {
arrResult.push(adminDb.database().ref('/fields/' + fields.key + '/fav').set(false));
}
});
}
}
});
}
}
});
});
return Promise.all(arrResult);
}).then((res) => {
console.log("check", res);
return response.status(200).json(res); // Fist response is [], if it a new request with the same values it works...
}).catch(err => {
return response.status(err.status >= 100 && err.status < 600 ? err.code : 500).send(err.message);
});
});

Categories