Node.JS req.body String Too Long? - javascript

I am once again asking a probably beginners question, but I have looked around quite a bit, and was unable to find the answer I need. I have created a Node.JS server pulling data for a Game State Integration project I am working on, and I need to request certain data from the game.
Basically, what is happening in the code is I am setting the variable newKillStatus to a certain part of the player_state file from which I am reading. Before I talk a bit further, here is the code I am using: (If you need more, please ask)
fs.readFile('player_state', 'utf8', function(err, killStatus) {
var player = 'player' in req.body ? req.body.player : null;
if (player && player.state !== killStatus) {
var newKillStatus = req.body.player.state.round_kills;
if (!newKillStatus) {
newKillStatus = '';
}
fs.writeFile('player_state', newKillStatus);
console.log(newKillStatus);
}
});
So as you can see I am trying to set newKillStatus to req.body.state.round_kills; which, from what I can understand is too long, because when I try to start the server, it gives me this error:
cannot read property 'round_kills' of undefined
But If I get rid of the round_kills part it gives me round_kills, but it also gives me a whole bunch of other statistics that I don't want to set the variable to.
So basically my only question is how can I set var newKillStatus to req.body.player.state.round_kills without an error.
Thank you for helping!
EDIT:
I have tried all the solutions and multiple combinations of strings, is it possible that the underscore is creating an error?

After several attempts to find the answer myself, I have found it. I am actually quite surprised it took me so long to spot this. The probably was actually above what I though was causing it, and what the error said was causing it. The problem was actually in var player = 'player' in req.body ? req.body.player : null; I needed to change req.body.player to req.body.player.state do the code below would know what I referencing.

Related

Node.js API requests randomly stopping

This is my first project, yes the code is bad, please be nice!
I'm working on a Discord Bot, which requests Game APIs for a whole Guild. First I get all the Ids for a guild into an array and then I make a get request for every Id.
My problem is, that the request just randomly stops after some time (always different), and I don't know why. It's also not giving an error.
I've already tried to run it from another program, change the package I'm using, look that the key can be used, but in the end, everything is the same.
while (guildmembers[i2] != undefined) {
console.log(guildmembers[i2])
let url = 'https://api.hypixel.net/player?key=' + APIkey
let Guildmembersuuid = guildmembers[i2]
let profilelurl = url + '&uuid=' + Guildmembersuuid
const TESTguildPlayerinfos = await axios.get(profilelurl)
console.log(TESTguildPlayerinfos)
i2++
}
If I did anything wrong with the post or didn't give enough information please tell me!
Thanks a lot for the help!
try using Promise.all(),which takes an array of promises and then put a catch block afterwards to see if there is any problem.
It looks like you are hitting the Hypixel throttling limits - you need to be more careful with your requests. As it stands, they will stop you at 120 requests/minute. You either need to manually throttle yourself like one member in the thread mentioned (waiting .5 seconds between any call to the API to ensure you don't overflow the limit) or insert a cache in between so that calls don't actually always land on the Hypixel backend.
https://hypixel.net/threads/api-request-limit.815723/

Embedded data in Qualtrics showing up in the 'Data & Analysis' tab, but is not showing up for participants

So I have a bit of JS in my Qualtrics survey that takes the response to a question, and if that response is not empty, it will embed the participant’s response (to be called later in the survey). If they don’t enter anything, I have made it print a string. I have done this with the following:
Qualtrics.SurveyEngine.addOnUnload(function()
{
/*Place your JavaScript here to run when the page is unloaded*/
var tboxID= "QR~"+this.questionId;
var hometownStr = document.getElementById(tboxID).value;
Qualtrics.SurveyEngine.setEmbeddedData('hometownStr',hometownStr);
if(!hometownStr || 0 === hometownStr.length)
{
Qualtrics.SurveyEngine.setEmbeddedData('hometownStr', "your hometown");
}
});
After the block this question is in I have embedded the data.
So, let's say I am asked the question (in which the JS is embedded): What is your hometown? I either answer that my hometown is (for example) "Paisley", or I leave it blank. If I don't answer the question, the next question will say This is a person from your hometown. If I
do answer the question, it should print: This is a person from Paisley.
However, the latter example does not print "Paisley" (it prints nothing). FYI, the former example works fine.
The strange thing is that, though "Paisley" is not printed in the survey, it comes out in the final data (found in the Data & Analysis tab).
Note: I am calling the embedded data by ${e://Field/hometownStr}.
Does anyone know why this might be happening? Thanks in advance for any help; please tell me I am stupid and overlooking something major, and this isn't a bug in Qualtrics...
FYI, this code has worked in the past, so I don't think it's an issue with the code. I refactored some of the questions and blocks and it just stopped working.
Move the survey flow embedded data block BEFORE the block where the JS sets it.
EDIT:
I noticed you are using addOnUnload. Use addOnPageSubmit instead.

Hubot nesting commands

I want to create a tree-style question and answer bot with hubot doing support services and I haven't been able to figure out how. I wanted Hubot to ask a question upon someone entering the room (with robot.enter) though that doesn't work with Rocket.Chat, I've found a workaround. But if I want to ask a question and wait for a user to reply to save their reply and ask them another question, how would I go about doing this?
I tried nesting even a res.send and it wouldn't allow me, giving me an index error on CoffeeScript
If you want something prebuilt, there are a couple framework scripts that provide this capability:
https://github.com/lmarkus/hubot-conversation
https://www.npmjs.com/package/hubot-dynamic-conversation
hubot-conversation is a little more JavaScripty (and ironically, a little more dynamic), whereas hubot-dynamic-conversation centers around you building a JSON model of the conversation flow.
If you don't like either of those options, you can always implement your own flow using a mixture of robot.listen to dynamically match messages and the brain to track state.
Example (that I haven't actually tested, but should give the right idea):
module.exports = (robot) ->
robot.respond /hello$/, (res) ->
res.reply 'Why hello there! How are you today?'
# Record that we are mid-conversation
convs = robot.brain.get('conversations')
convs = convs.push(message.user.name)
robot.brain.set('conversations', convs)
robot.listen(
# If we are mid-conversation, respond to whatever they say next
(message) -> message.user.name in robot.brain.get('conversations')
(response) ->
response.reply 'I hope you have a great rest of the day!'
# Record that we are done conversing
convs = robot.brain.get('conversations')
convs = convs.splice(convs.indexOf(message.user.name), 1)
robot.brain.set('conversations', convs)
)
According to https://github.com/github/hubot/blob/master/docs/scripting.md
You can just use:
robot.enter (res) ->
res.send res.random enterReplies
don't know whether still have solution on this, since TS mention robot.enter in rocketchat does not work.

Sending messages across channels with Discord.js, yields 'undefined' error

I'm looking to create a 'say' command that allows me to directly message through the bot to a specific (or any, perhaps) channel. For beginner, and general testing purposes, my goal is to be able to use a standard if(commandIs("command", message) to directly message a channel in my test server, eventually evolving to all channels on a server.
Through my research I've stumbled upon the:
var channel = client.servers.get("name", "My Server").defaultChannel;
client.sendMessage(channel, "Hello");
code, which is exactly what I'm looking to do as a base since I can swap out the .get("name", "My server") for the actual channel ID, but doing this through a say-like command sets the var as a Channel class in my code, which doesn't support .sendMessage()
My current command code looks like:
if(commandIs("speak", message)){
var chat = client.channels.get(18numberID);
if(args.length === 1){
message.channel.sendMessage('You did not say anything. Usage: `a~speak [message]`')
} else {
chat.sendMessage(args.join(" ").substring(8));
-but this brings up an undefinederror on the .sendMessage(), which I figured it would. I've tried message.chat.sendMessage() and every other possible variation I could, even going to the bare two lines of code to test at on.ready(), but that continued to give me the same error. I've looked for a way around the Channel class created once the ID is found and that led me to the TextChannel and GuildChannel extensions, but I'm pretty sure there's an easier way around it considering all the code (even a couple examples here) do not contain all that extra information. I feel like I'm looking over something, or possibly complicating the code more than needed, but I'm not sure.
Any ideas or help would be appreciated.
Edit: It seems I was right and I looked over a few key points, specifically the channelID not having quotes around it to be a string. Tried the command alone and everything went great; tweaked the main code and it all worked out.
First of all, I just have to outline a few things that no longer work in the Discord.JS library (Thanks for the heads-up Ty Q.!)
First of all, .sendMessage() has been deprecated, and will more than likely not work at all anymore / soon. The working equivalent of this is .send() - which is simpler, and is an easy change to make.
Second: .defaultChannel is unfortunately no longer a thing. We will have to be more specific when we want to send a message.
I'm not great at talking about these kinds of issues, so if anyone else wants to pick it up, please do.
Alright, let's let your command be set out like this:a~speak [ChannelID] <Message>
Let's say we use this command: a~speak 12345689 I has a bucket
What we want to do is find out whether we can find the channel with the ID, and if we can, send the message to it.
To do that, I think we should see if we can use the client.channels.find("id", ID) function.
Let's Start by Setting Up Our Command
if(commandIs("speak", message)){
args = args.shift();
/* ["a~speak", "CHANNELID", "I", "has", "a", "bucket"]
BECOMES
["123456789", "I", "has", "a", "bucket"]
args [0] [1] [2] [3] [4]*/
let chan = client.channels.find("id", args[0]); // Find the channel ID "123456789"
if(chan) { // Check if that channel exists
chan.send(args.shift().join(" "));
} else {
message.channel.send(args.join(" "));
}
}
Let's Follow That Command
If we type in a~speak 12345689 I has a bucket, our bot will look for a channel that it has access to with the id "123456789".
If your bot found the channel with the id "123456789":
chan.send(args.shift().join(" "));
We defined earlier that chan = args[0] - which would be "123456789", and we don't want to send that in the message, so we use args.shift() - this removes the first argument from the rest, leaving us with ["I", "has", "a", "bucket"].
After that, we use .join(" ") - this connects ["I", "has", "a", "bucket"] with spaces to form I has a bucket.
We then simply send that message to the channel we defined, with chan.send().
If your bot did not find the channel with the id "12456789"
message.channel.send(args.join(" "));
This one's a bit different in a few ways, first of all, we forget about the chan variable, because we couldn't find that channel. If we know this, we can deduce that the user may have instead said something like a~speak I has a bucket - without the ID altogether.
Knowing that, we (unlike before), don't want to args.shift() - we would remove the "I" bit! Instead, we just want to args.join(" ") to once again join the words together into a sentence, then send it away with message.channel.send() - which just sends it in the server it got the message from.
If you need any more help, just comment with your Discord name, and I'll be happy to give you a little push in the right direction.
Sources of Information:
Some good places to look for help on these kinds of topics (Discord.JS), are the Official Discord.JS Server and AnIdiotsGuide. Both of which will be able to solve your problems.

Find all class and id names in an Ace Editor HTML script

What I'm trying to do:
Collect all the class and id names in an Ace Editor html script.
Right now my plan is to detect user changes (.on('change'...)) and get the current token using the cursor position. If the token is a not 'unquoted' 'attribute-value' type, I want to iterate back through previous tokens in order to find the 'attribute-name' type token to which that 'attribute-value' belongs and identify whether it is a class or id (I can't just detect the creation of an 'attribute-name' token because the user can go back and change the attribute-values later without changing the name, and I need to detect those changes).
I can do everything except for get previous tokens. I looked up some documentation and the TokenIterator is supposed to be able to do that, but when I try to do something like var iter = new TokeIterator(), my console says that TokenIterator is undefined. I've searched google over and over, but found no results. If the truth is out there I'm obviously not using the right words to find it, but they're the only words I've got.
Is some way built into Ace to iterate through tokens? I know I'm not seeing all the properties and methods on the editor instance object when I console log it, because I can use methods in my script that I can't see in that log. Is there one there that does what I want?
If not, how do I load the TokenIterator? I think something similar went on when I tried to use SnippetManager a while back and it turned out I actually had to do this to make it work:
var tillPageLoaded = setInterval(function() { // Makes sure page doesn't load forever on startup
if( document.readyState === 'complete') {
clearInterval(tillPageLoaded);
ace.config.loadModule('ace/ext/language_tools', function () {
editor.insertSnippet( myString );
});
}
}, 5);
Is this the same kind of situation? If so, what needs to be in .loadModules(...)? Do I need to reference a script somewhere? Does it need to be loaded some other way?
Is there built in functionality for Ace that would already do everything I want?
Other than that, if anyone has any better ideas of how to go about this with Ace, those would be very welcome.
you can get TokenIterator by using
var TokenIterator = ace.require("ace/token_iterator").TokenIterator
see https://github.com/ajaxorg/ace/blob/master/lib/ace/mode/folding/xml.js#L38 for an example of its usage.

Categories

Resources