Node.JS asynch with req.session.variable? - javascript

router.get("/roll", function (req, res) {
//Re-enable the session.
//req.session.isrolling = 1;
if(typeof req.session.isrolling === "undefined") {
console.log(classname + "** setting the variable **");
req.session.isrolling = 1;
}
console.log(classname + "[0]" + req.session.isrolling);
if(req.session.isrolling == 1 || req.session.isrolling == 3) {
console.log(classname + "[1] " + req.session.isrolling);
req.session.isrolling = 0;
console.log(classname + "[2] " + req.session.isrolling);
As you can see, little obvious, I uncomment the 3rd line to re-enable incase I stucked myself with 'debugging'.
Anyways the outputs are normally;
[index.js] [0]3
[index.js] [1] 3
[index.js] [2] 0
I use an boolean to try and check where it goes wrong.
Anyways after some callbacks and functions within functions I end on this part -
rollController.UpdateDeposit(true, winAmmount, req.session.userSecret, function(callbackresult) {
if(callbackresult) {
console.log(classname + "[3]" + req.session.isrolling);
req.session.isrolling = 3;
console.log(classname + "[4]" + req.session.isrolling);
}
Despite all of this, and the expected 'outputs', I can keep spamming while an roll is pending while the console hasn't even outputted;
[index.js] [3]0
[index.js] [4]3
If I try to create an local variable within index.js (ofcourse not the optimal way) it fixes it, but its 1 query per, and not per user (dumb yes).
I added the undefined thing, it happends when I mess around with mySQL and reset some data. I am wondering myself if I should switch to mongoDB due performance but that might something for later.
So the main question is, where do I go wrong and what would be an better approach to make a queue per user(session?) and, obvious, not per server ?

I finally found the solution.
This kept me busy for a large week, while reading a lot, and learning more, about node.
req.session.save(function(error) {
console.log(classname + " Error in saving session " + error)
});
Thank you achmad.

Related

JavaScript: Uncaught TypeError when accessing a smaller array than the last load

I am very new to JavaScript (been programming Arduinos and Python for some time now) and have been following a tutorial for making a calendar showing events for 1 month at a time.
When not populating the calendar, there is no issues.
When populating the calendar with events (work schedule for a fire dept., so I'm afraid I cant show pictures of the project), I get a Uncaught TypeError when accessing information in an array shorter than the previous (being that February has less days than January, hence reading from an array with a length of 28 instead of a length of 31).
When I console.log() it, the first 28 reads just fine, after that the error comes event though I wouldn't expect it to look for more instances than the 28
Now, the js just jQueries the entire years worth of data into an array when loading the page - it come from at database on another server.
Then, when loading the page, my calendar starts at the month we're currently in. From there, you can go to next month or the previous month and so forward.
Every time the month is changed, a function named load() is called, updating the month.
What I've build in, is a new function loading a new set of events for the next month loading.
function findMaanedsEvents(maaned) {
let maanedens_events = [];
let eventtaeller = 0;
for (i = 0; i < requestdata.length; i++) {
let reqm = requestdata[i]['dato'].split('-');
if (reqm[1] == maaned) {
maanedens_events[eventtaeller] = requestdata[i];
eventtaeller ++;
}
}
return maanedens_events;
}
requestdata is the result of the jQuery. The return is saved into an array and is working just fine. It returns the right set of data and the correct length.
The month showing part of it works just fine. It's the event part that's not behaving.
with 'nav' being the integer that holds the number for which month we want displayed, I try to populate using the data like so:
for(let i = 1; i <= paddingDays + daysInMonth; i++) {
const daySquare = document.createElement('div');
daySquare.classList.add('day');
if (i > paddingDays) {
daySquare.innerText = i - paddingDays;
dagens_events =
dagsevents[i - paddingDays - 1]['bm1'] + "\n" +
dagsevents[i - paddingDays - 1]['bm2'] + "\n" +
dagsevents[i - paddingDays - 1]['bm3'] + "\n" +
dagsevents[i - paddingDays - 1]['bm4'] + "\n" +
dagsevents[i - paddingDays - 1]['bm5'];
const eventDiv = document.createElement('div');
if (dagsevents[i - paddingDays - 1]['helligdag'] == 1) {
eventDiv.classList.add('helligdag_event');
}
else {
eventDiv.classList.add('event');
}
eventDiv.innerText = dagens_events;
daySquare.appendChild(eventDiv);
console.log(dagsevents[i - paddingDays - 1]['bm1']);
}
else {
daySquare.classList.add('padding');
}
calendar.appendChild(daySquare);
}
As mentioned, this works fine if the month being loaded has an equal or greater number of days.
If it has less though, I get this console.log:
console.log
'bm1' being 1 of 5 names showing as 1 event for the day - I just logged it for debugging purposes. The red lines is just the names for the 'bm1' key that I've blurred out.
At first, I though the issue was that my array had too many indexes, the last ones just empty. But by console.logging it, I see that the length of the array matches the number of days in the month for every load that I do.
I've tried fiddling around and Googling. I've tried going away for a while to come back and have another go at it, but I can't seem to wrap my head around it.
As I noted, I am very new to JavaScript and it could be me overlooking something completely basic - bear with me.
Found the solution - sorry for asking, but I've been trying for hours without luck.
It turned out that even though the array was returned with only the 28 days for february, the 3 last (28-31 january) was in fact still indexed in the array, even though it was not containing anything.
The solution was to put the codeblock inside an if-statement checking for content of the xth row in the event array and only firing with it was not undefined.
Like so:
if (dagsevents[i - paddingDays - 1] != undefined) {
daySquare.innerText = i - paddingDays;
const dagens_events =
dagsevents[i - paddingDays - 1]?.['bm1'] + "\n" +
dagsevents[i - paddingDays - 1]?.['bm2'] + "\n" +
dagsevents[i - paddingDays - 1]?.['bm3'] + "\n" +
dagsevents[i - paddingDays - 1]?.['bm4'] + "\n" +
dagsevents[i - paddingDays - 1]?.['bm5'];
const eventDiv = document.createElement('div');
if (dagsevents[i - paddingDays - 1]?.['helligdag'] == 1) {
eventDiv.classList.add('helligdag_event');
}
else {
eventDiv.classList.add('event');
}
eventDiv.classList.add('event');
eventDiv.innerText = dagens_events;
daySquare.appendChild(eventDiv);
}
I dont know if my answer is beneficial to anyone, but here it is.
I'm sure there's much cleaner and smoother ways to go about this problem. I'm still learning overall in programming an especially in Javascript.
Therefore, please let me know if you got a smoother and/or better solution to this problem :)
Cheers.

Im doing a JavaScript CodeHS course, but what am I doing wrong?

Im doing intro to JS in a site called CodeHS. I believe I did the assignment its asking of me right but it says its wrong?
Here is what it wants me to do:
Here is what I did:
Heres what I apparently got wrong:
Ive run this code many times and it worked flawlessly, so why does it give me these errors?
You forgot to add a blank line inside the end of your while block, which also accounts for the line number. You should check the IMPORTANT note on the assignment.
I agree with #Jorge. You need to include the new line character '\n' at the end of the appropriate print statements, for the sake of the marking program. Try it like this:
while(numItems > 0) {
println('We have ' + numItems + ' in inventory.');
var buy = readInt('How many items would you like to buy?');
if(buy <= numItems) {
numItems -= buy;
println('Now we have ' + numItems + ' left.' + '\n');
} else {
println('There is not enough in inventory for that purchase.' + '\n');
}
}

How to setup position with FEN string in stockfish.js?

I want to make a chess puzzle on my website for my student.
I use stockfish.js to play with the engine.
How to change the start position on the board?
I try to change all FEN string but did not work.
Where to look for the function or something?
Anybody can help me, please?
Interacting with the javascript port of Stockfish is (at time of writing) still like communicating with a chess engine that uses/supports UCI (Universal Chess Interface).
The UCI position command should suffice:
var fenString = "rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - 0 2"
// start UCI
stockfish.postMessage("uci");
// start new game
stockfish.postMessage("ucinewgame");
// set new game position
stockfish.postMessage("position fen " + fenString);
// start search
stockfish.postMessage("go depth 10");
Edited: Updated case for postMessage() function.
I was working on the same thing and figured it out -- it's by no means obvious and within the stockfish example there are lots of little trips and pitfalls. I found a couple questions online and thought I'd give them some answers.
So -- this answer assumes working with the example code found here: https://github.com/nmrugg/stockfish.js/tree/Stockfish11/example.
There are two major modifications that need to happen - first in the index.html file and second in enginegame.js.
First we'll define a helper function which will make it easy to work with the url "search" as it's called:
function searchToObject() {
var pairs = window.location.search.substring(1).split("&"),
obj = {},
pair,
i;
for ( i in pairs ) {
if ( pairs[i] === "" ) continue;
pair = pairs[i].split("=");
obj[ decodeURIComponent( pair[0] ) ] = decodeURIComponent( pair[1] );
}
return obj;
}
For ease I just placed that function in both files, within index.html it's at the beginning of the script tag, in enginegame.js it's the very first line. Also btw, I certainly pilfered that from stackoverflow, but I can't seem to find that answer any more, rats.
In index.html the newGame function wants to look like this:
newGame = function newGame() {
var baseTime = parseFloat($('#timeBase').val()) * 60;
var inc = parseFloat($('#timeInc').val());
var skill = parseInt($('#skillLevel').val());
game.reset();
let search = searchToObject();
if (search.player) {
game.setPlayerColor(search.player)
} else {
game.setPlayerColor($('#color-white').hasClass('active') ? 'white' : 'black');
}
if (search.fen) {
game.game.load(search.fen);
game.board.position(game.game.fen());
}
game.setTime(baseTime, inc);
game.setSkillLevel(skill);
game.setDisplayScore($('#showScore').is(':checked'));
game.start();
}
Note the game.game and game.board -- those need to be added in enginegame.js where it's returning an object. If I were writing this I would have done it differently, but I didn't have the patience to rename things.
Next up in enginegame.js we need to adjust prepareMove.
function prepareMove() {
stopClock();
$('#pgn').text(game.pgn());
board.position(game.fen());
updateClock();
var turn = game.turn() == 'w' ? 'white' : 'black';
if (!game.game_over()) {
if (turn != playerColor) {
let search = searchToObject();
if (search.fen) {
uciCmd('position fen ' + search.fen + ' moves ' + get_moves());
} else {
uciCmd('position startpos moves' + get_moves());
uciCmd('position startpos moves' + get_moves(), evaler);
}
evaluation_el.textContent = "";
uciCmd("eval", evaler);
if (time && time.wtime) {
uciCmd("go " + (time.depth ? "depth " + time.depth : "") + " wtime " + time.wtime + " winc " + time.winc + " btime " + time.btime + " binc " + time.binc);
} else {
uciCmd("go " + (time.depth ? "depth " + time.depth : ""));
}
isEngineRunning = true;
}
if (game.history().length >= 2 && !time.depth && !time.nodes) {
startClock();
}
}
}
See, the trick is that if ever there was a fen string to start the game, every subsequent position call needs to be different. I think that's probably what's tripping most people up - that's definitely what got me.
What helped things click for me was reading through the UCI documentation. Before that my board was in some crazy infinite loop.
Also one weird but critical bit I stumbled onto was the game.game.load(<fen string>) function call in the index.html file. I can't find any documentation for that. I don't even remember how I found it. But there it is!

setTimeout for client using command

So what I'm trying to do is create a "cooldown" like system for my discord bot, I've tried using a database method, here which doesn't work for me.
I'm using the discord.js package.
Here is my code:
if (msg.content.startsWith("!point")) {
var usr = msg.content.split(" ").slice(1).join(" ");
if (!usr) {
bot.sendMessage(msg, "```Error: 1\n Reason: Please state a name.```");
return;
}
if (usr == msg.author.username) {
bot.sendMessage(msg, "```Error: 3\n Reason: You're unable to point yourself.```");
return;
}
if (!db["users"][usr]) {
db["users"][usr] = 0;
}
console.log(usr + " has " + db["users"][usr]);
db["users"][usr] += 1;
console.log(usr + " now has " + db["users"][usr]);
fs.writeFileSync('database.json', JSON.stringify(db));
bot.sendMessage(msg, usr + " has received 1 point");
}
Unless it's very important that the cooldown survives a crash, or the cool down is a very long duration I recomend creating an object with keys that are are either channel or user or server id's depending on what you want the rate limit to apply to. Then every time a command is run set that to the current time. Something like
rateLimitObject[msg.author.id] = "current time";
Then whenever someone runs a command just ensure that the current time is greater than the time in the object with that index by more than a certain amount.
If you are looking to just simply stop people from spamming the command something similar to what's used in pvpcraft here may be more ideal.
https://github.com/macdja38/pvpcraft/blob/master/middleware/rateLimits.js

Can you run a JS if statement and for loop inside a line of JQuery?

I am very new to learning both Javascript and Jquery.
In the website I am creating I am trying to insert a Javascript if statement and a for loop in a line of JQuery. The last confirm does not run. I suspect it is the if statement that is causing the issue. How can I fix this? Here is how my code looks like.
$(document).ready(function() {
$(".button3").click(function() {
var lastname = $('#lastnameresponse').val();
confirm("You're last name is" + " " + lastname);
if (userResponse = "girl") {
for (var i = 0; i <= girlnames.length; i++) {
confirm("Your future daughter's name is" + " " + random + " " + randomagain + " " + lastname);
})
});
There's a lot that doesn't make much sense with your code.
First, what is userResponse? Where does this get defined and where is it set? Have you verified under a debugger that it is indeed equal to "girl"?
Second, you probably meant to use a comparison equals not an assignment equals here:
if (userResponse = "girl") { // This should be ==
However, this should not prevent the block from running. In fact, it will force the block to always run since "girl" is true-ish.
Third, what is girlnames? Is it an array? Where is this defined? Have you verified it indeed contains valid items?
Lastly, I believe your for loop is incorrect:
for (var i = 0; i <= girlnames.length; i++) {
Should be:
for (var i = 0; i < girlnames.length; i++) {
Arrays start at 0, thus girlnames[girlnames.length] is not a valid item.
However, considering you don't use the i variable in your loop anywhere, again this should not actually cause any errors.
I would step through your code line by line using a script debugger (usually F12 in modern browsers) and set a break point at:
var lastname = $('#lastnameresponse').val();
Then verified each line is behaving correctly. If that still doesn't work, you'll need to post more of your code so we can get a better idea of what's going on.
UPDATE:
Based on your comment:
Here is where the userResponse variable is defined:
$(document).ready(function(){ $("#girlimg").click(function() { var
userResponse = prompt("Confirm the gender you selected").toLowerCase;
$('html, body').animate({ scrollTop: $(".LastName").offset().top },
2000);
It seems that userResponse gets declared within the click handler for the #girlimg tag:
$("#girlimg").click(function() {
// Everything declared here is local to this function
var userResponse = confirm(); // local variable
});
Thus, it would not be accessible in the click handler for .button3. You'll need to declare userResponse in a scope that is accessible to both functions. Perhaps global (this is frowned upon in JavaScript) or within your $(document).ready() code, provided both click event handlers are defined within that block.
First: it's Your not You're :)
Secondly, userResponse is undefined. Maybe it's defined somewhere else.
For comparison, use == operator.
Are you sure is that what you want to do? I see you also have confirm there.
Use confirm like this:
$(".button3").click(function() {
var lastname = $('#lastnameresponse').val();
// confirm() returns true or false, depending on the clicked button
is_confirmed = confirm("You're last name is" + " " +lastname);
if (true == is_confirmed) {
for (var i = 0; i <= girlnames.length; i++) {
confirm ("Your future daughter's name is" + " " + random + " " + randomagain + " " + lastname);
}
}
});
girlnames is also not defined here (maybe it's somewhere else). Same for random and randomagain
As for writing JavaScript "in" jQuery: there is no such question. jQuery is a library written in Javascript that provides useful functions to ease development.
Following statement does not contain a proper JavaScript Comparison Operator
equals is written ==
if (userResponse = "girl") {
for reference look here
you forgot to close some arrows, any way when you put :
if (userResponse ="girl"){...}
you set userResponse variable to "girl", and that passes the value to the variable only
to check in the userResponse is equal to "girl" you should put
if (userResponse =="girl")
your final code will look like this
$(document).ready(function(){
$(".button3").click(function() {
var lastname = $('#lastnameresponse').val();
confirm("You're last name is" + " " +lastname);
if (userResponse ="girl") {
for (var i = 0; i <= girlnames.length; i++) {
confirm ("Your future daughter's name is" + " " + random + " " + randomagain + " " + lastname);
}}}
)
});
p.s:you forgot to close too many arrows

Categories