ive made a function for my twitch bot. which when they input a command checks if they are already in the list. if they are not in the list it will add them to the list. The code below outputs this : [ undefined ]
[17:53] info: [#kong_plays] *<kng_bot>: 1
var wtpLength = [];
function lfg(user){
WTPLength = viewersWTP.length;
if (WTPLength !== 0) {
viewersWTP = viewersWTP - 1
while(WTPLength !== -1){
if(user === viewersWTP[WTPLength]){
console.log("Already in list")
client.action("kong_plays",user+" you cannot execute this command again until kong pulls a viewer to play with him!")
}else{
viewersWTP.push(user['display-name'])
console.log("Added into list")
client.action("kong_plays",viewersWTP)
}
}
}else{
viewersWTP.push(user['display-name'])
console.log(viewersWTP)
client.action("kong_plays","1"+viewersWTP)
}
}
Something like this may work for you. You are using variables that are undefined. It also looks as though you are not paying attention to the cases of the variables that you are defining.
var viewersWTP = []; // add this or define it elsewhere
function lfg(user){
var wtpLength = viewersWTP.length;
if (wtpLength !== 0) {
viewersWTP = viewersWTP - 1
while(wtpLength !== -1){
if(user === viewersWTP[wtpLength]){
console.log("Already in list")
client.action("kong_plays",user+" you cannot execute this command again until kong pulls a viewer to play with him!")
}else{
viewersWTP.push(user['display-name'])
console.log("Added into list")
client.action("kong_plays",viewersWTP)
}
}
}else{
viewersWTP.push(user['display-name'])
console.log(viewersWTP)
client.action("kong_plays","1"+viewersWTP)
}
}
Change the user['display-name'] into user. You passed that var throught the function
Related
I have function that creates a team and puts data to database. Now I'm trying to check if team already exists, if it does exists then reply with message. I have problem with my if statement.
if (result[0].teamname == teamName)
When result[0].teamname is undefined it shows Cannot read property 'teamname' of undefined it ignores else and throws an error. How can I make so that does not ignore else?
Here is the function I use to create team.
function createTeam(teamName, members, message) {
teamName = teamName.replace("_", " ");
let insertTeam = `INSERT INTO teams (teamname) VALUES ('${teamName}');`;
db.select(`SELECT id_t, teamname FROM teams WHERE teamname = '${teamName}'`, function(err, result) {
if (err) {
throw err;
} else {
if (result[0].teamname == teamName) {
if (message.guild !== null) message.delete();
message.reply("this team already exists!");
} else {
db.query(insertTeam);
db.select(`SELECT id_t FROM teams WHERE teamname = '${teamName}'`, function(err, result) {
if (err) {
throw err;
} else {
for (let i = 0; i < members.length; i++) db.query(`INSERT INTO team_user (user, team) VALUES ('${members[i]}' , ${result[0].id_t})`);
}
});
if (message.guild !== null) message.delete();
let newTeam = new Discord.RichEmbed()
.setThumbnail("https://cdn.discordapp.com/emojis/542789472421675028.png?v=1")
.setColor("#15f153")
.addField("New team has been created!", `Team ${teamName} has been created with total of ${members.length} members!\nGood luck!`);
message.channel.send(newTeam);
}
}
});
What have I tried so far:
Checking if result[0].teamname is undefined
Checking if result length is not 0
try-catch statement
if (result[0] && result[0].teamname == teamName)
First of all you need to check if result[0] is not undefined
You need to short-circuit the condition. All this means is you want to first check that result exists before checking properties of result
So for example, your code should look like this:
if (result && result[0] && result[0].teamname == teamName) {
//Do something
}
If result is array with more then one value, then you need to iterate over every one of them, you can use filter array method for this:
var found = result.filter((row) => row.teamname == teamName);
if (found.length) {
}
You can also as #ThomasKleßen mention in comment check if result is not undefined:
var found = result && result.filter((row) => row.teamname == teamName).length;
if (found) {
}
You can always do a default value
if ((result || [{}])[0].teamname == teamName)
If the result is falsy, it will default to an array of an empty object, which will allow for the array access and dot notation to work, but the equality to fail.
I'm trying to call a function that gets a channel ID when given a Slack Workspace and channel name. I can get the correct result within the function, but when I try to call the function elsewhere, it is returning undefined.
Function to get the channel ID `
//GET CHANNEL ID FROM LIST OF ALL CHANNELS IN WORKSPACE
function getChannelID(workspaceName, pageLimit, channelName, nextCursor){
var channelListResponseURL = 'https://slack.com/api/conversations.list';
var payload = {
'limit': pageLimit,
'types': 'public_channel, private_channel',
'cursor' : nextCursor
};
var options = createURLargs(workspaceName, payload);
var channelListResponse = UrlFetchApp.fetch(channelListResponseURL, options);
var channelListJson = channelListResponse.getContentText();
var channelListData = JSON.parse(channelListJson);
//iterate through each channel in the returned JSON object and sets the channel ID for the one matching the channelName
for (var i in channelListData.channels){
if(channelListData.channels[i].name == channelName){
var channelID = channelListData.channels[i].id;
Logger.log('FOUND CHANNEL ID: '+ channelID);
return channelID;// IF CHANNEL ID FOUND, THEN EXIT getChannelID FUNCTION AND RETURN CHANNEL ID
}
}
// IF NO CHANNEL ID IS FOUND, THEN CHECK TO SEE IF PAGINATION IS IN EFFECT, UPDATE CURSOR, AND RERUN getChannelID FUNCTION
if (channelListData.response_metadata.next_cursor && channelListData.response_metadata.next_cursor != ""){
nextCursor = channelListData.response_metadata.next_cursor;
getChannelID(workspaceName, pageLimit, channelName, nextCursor);
} else {
// IF CHANNEL PAGINATION IS NOT IN EFFECT, OR REACHED LAST PAGE AND NO RESULT IS FOUND
return 'No Channel Found in Workspace';
}
}
`
I can clearly see the 'FOUND CHANNEL ID: CXXXXXX' string in the logger, so I'm sure it finds it properly.
But when I call this getChannelID from the main function, it is returning undefined.
var channelID = getChannelID(workspaceName, pagLimit, channelName, nextCursor);
Logger.log(channelID);
The weird thing is this seems to work when the JSON object from Slack isn't paginated, but when the results are returned paginated, I just seem to get undefined.
Any ideas why the result it's returning is undefined, even though it works in the function?
I think that in your recursive function, the value is not returned. So how about this modification?
From :
if (channelListData.response_metadata.next_cursor && channelListData.response_metadata.next_cursor != ""){
nextCursor = channelListData.response_metadata.next_cursor;
getChannelID(workspaceName, pageLimit, channelName, nextCursor);
} else {
// IF CHANNEL PAGINATION IS NOT IN EFFECT, OR REACHED LAST PAGE AND NO RESULT IS FOUND
return 'No Channel Found in Workspace';
}
To :
if (channelListData.response_metadata.next_cursor && channelListData.response_metadata.next_cursor != ""){
nextCursor = channelListData.response_metadata.next_cursor;
return getChannelID(workspaceName, pageLimit, channelName, nextCursor); // Modified
} else {
// IF CHANNEL PAGINATION IS NOT IN EFFECT, OR REACHED LAST PAGE AND NO RESULT IS FOUND
return 'No Channel Found in Workspace';
}
Note :
When channelListData.response_metadata.next_cursor && channelListData.response_metadata.next_cursor != "" is true, no value is returned. So I added return.
If this didn't work yet, please tell me. I would like to modify it.
Added :
In my understanding, when the recursive function is run, the process returns to the line which was run. In order to confirm this, I prepared 3 sample functions.
Function 1
function foo1(value) {
if (value == "") {
foo1("bar");
} else {
return "ok";
}
}
Function 2
function foo2(value) {
if (value == "") {
return foo2("bar");
} else {
return "ok";
}
}
Function 3
function foo3(value) {
if (value == "") {
foo3("bar");
}
return "ok";
}
When these functions is run by as follows,
var res1 = foo1("");
var res2 = foo2("");
var res3 = foo3("");
res1, res2 and res3 are undefined, ok and ok, respectively.
I can't get tracks to skip on our music bot without it panicking and deleting the entire playlist. More details below.
On command, this bot will use YouTube-DL to download a video from YouTube or track from BandCamp and play it back through a voice channel. The track is downloaded, loaded into an array and they play back one after the other. When the track finishes, it moves on to the next without a problem. But when it comes to skipping tracks manually, it's like the whole function bugs out and runs repeatedly until the playlist is empty and the files have been removed.
A few variables to get us started:
// References
var VC;
var TC;
var AS;
var DS;
var playlist = new Array();
var reqlist = new Array();
var volume = 100;
var fulltitle;
This is the function that goes to the next track:
function Next()
{
if(!(DS===undefined)) DS.pause();
if (playlist.length > 0)
{
// Delete the first audio file in the list (the one that just finished)
var fileRemove = false
try {
fs.remove(playlist[0].file)
console.log('File removed!');
fileRemove = true
} catch(e) {
fileRemove = false
console.err(e)
}
if (fileRemove = true) {
playlist.splice(0, 1);
console.log('Spliced!');
} else {
console.err('Could not splice or file not removed.')
}
//console.log(playlist)
//fulltitle = playlist[0].info.fulltitle
return StartPlay();
}
console.log('Length: ' + playlist.length)
if(playlist.length === 0) {
client.user.setPresence( { status: 'idle', game: { name: null } } )
}// else {
// // Start playing
// return StartPlay();
// }
}
Here's StartPlay():
function StartPlay() // Automatically plays queue once a song has been added successfully
{
if (playlist.length >= 1) {
// Play the audio file
DS = AS.playFile(playlist[0].file);
DS.passes = 12;
DS.setVolume(volume/200.0);
//fulltitle = playlist[0].info.fulltitle
// Display song title in 'Game played'
client.user.setPresence({ status: 'online', game: { type:2, name: fulltitle } });
// Once the song is done
DS.on('end', reason => {
// Go to the next track
Next();
});
}
}
And here's the command to get it to skip:
case 'skip':
if(VC===undefined) return;
if(TC===undefined) return;
if(!CheckTCVC(message)) return;
if(playlist.length === 0) return message.channel.send('There is nothing to skip.');
if(playlist.length === 1) return message.channel.send('There is nothing to skip to. Queue something else first or use `' + prefix + 'leave`.')
if(message.content.length > 5) {
const trackNumber = parseInt(message.content.split(' ')[1])
if (trackNumber !== 1) {
fs.remove(playlist[trackNumber-1].file).then(() => {
console.log('File removed!');
playlist.splice(0, trackNumber-1)
message.channel.send('Future song skipped!')
}).catch(err => {
console.error(err)
})
} else {
Next();
message.channel.send('Current song skipped!')
}
} else {
Next();
message.channel.send('Song skipped!')
}
break;
I'm not sure what else anyone will need from the code. Just let me know and I'll paste it in.
Here's a link to the Discord.JS documentation, not that I think it's really needed here: https://discord.js.org/#/docs/main/stable/general/welcome
Thanks in advance!
When you call playlist.splice(0, trackNumber-1), I believe you're using splice wrong. According to the MDN documentation, splice has two arguments: The starting position, and the amount of elements to remove. You've put 0 as your position, and trackNumber as the amount to remove. So if track number is 42, you'll remove 42 elements from the array. Try using playlist.splice(trackNumber-1, 1) to see if that gives you the desired effect.
I have this example code
var randFriend = friendList[Math.floor(Math.random() * friendList.length)];
if (randFriend == admin) {
//Here
}
else if (randFriend != admin) {
client.removeFriend(randFriend);
}
How can I do if if randfriend == admin to do again var randFriend = friendList[Math.floor(Math.random() * friendList.length)]; and check if(randFriend == admin) again. In other words, to restart that again.
I think that it's done with return, but I don't know. Thanks
I wouldn't use recursion or loops with random conditions, because you will have problems to estimate the runtime, and if the use case changes and you would have more elements you want to ignore, then the probability to find the correct element will decrease.
A better idea would be to filter the array to remove the elements you want to ignore and then pick a random element from that list.
var nonAdminList = friendList.filter(person => person != admin);
if( nonAdminList.length === 0 ) {
throw new Error('no non admin persons available');
}
client.removeFriend(nonAdminList[Math.floor(Math.random() * nonAdminList.length)]);
If I'm understanding the question correctly, you could use a while loop to keep randomizing until an admin isn't selected
var friendAdmin = true;
var randFriend;
while(friendAdmin){
randFriend = friendList[Math.floor(Math.random() * friendList.length)];
if(randFriend != admin) friendAdmin = false;
}
client.removeFriend(randFriend);
I would put your code into a function so that you can invoke the function again if you want to repeat it. For example:
function choose(){
var randFriend = friendList[Math.floor(Math.random() * friendList.length)];
if(randFriend == admin){
choose(); //this repeats the choose function, which will run the random friend code again
}
else if(randFriend != admin){
client.removeFriend(randFriend);
return; //this exits the function
}
}
I am writing Azure Mobile Service (AMS) API with JavaScript backend named customertickets and in the .get function I am attempting to read values from two tables in my AMS.
The two tables are 'User' and 'Ticket' and I am attempting to retrieve all tickets based on the passed parameter (phonenumber) and return some statistical data. Additionally, I am injecting a custom return value item.spname when looping through the tickets if the ticket satisfy a certain condition (item.parsedjsondata.SPId is not null or empty).
Here is the complete code (ctrl+F 'THIS DOES NOT WORK!'):
//Get ticket info by customer phonenumber
exports.get = function(request, response) {
var phonenumber = request.query.phonenumber;
var activeTicketsCounter = 0;
var completedTicketsCounter = 0;
var canceledTicketCounter = 0;
var needCustomerRatingTicketCounter = 0;
var includeCounterData = request.query.includeCounterData;
console.log("customertickets/get phonenumber: " + phonenumber);
request.service.tables.getTable('Ticket').read({
//SEE: http://stackoverflow.com/questions/24406110/how-to-get-system-properties-createdat-version-in-javascript-backend-of-azu
systemProperties: ['__createdAt', '__updatedAt'],
success: function(result) {
//No ticket is found
if (result.length === 0) {
console.log("customertickets/get: no ticket found");
response.send(statusCodes.NOT_FOUND, { message: "customertickets/get: no ticket is found" });
}
//return tickets after filtration based on the customer phonenumber
else {
console.log("customertickets/get: ticket found");
var filteredResults = [];
result.forEach(function(item) {
//only tickets with matched phonen number
if (JSON.parse(item.jsondata).customerPhonenumber == phonenumber) {
console.log(item);
//Adding parsed jsondata to item
item.parsedjsondata = JSON.parse(item.jsondata);
//Adding the name of the assigned spid; only if spid is not null ie. ticket is already assinged
if (item.parsedjsondata.SPId) {
console.log("SPID", item.parsedjsondata.SPId);
console.log("customerId", item.parsedjsondata.customerId);
//This works as expected
item.spid = item.parsedjsondata.SPId;
request.service.tables.getTable('User').where({ id: item.parsedjsondata.SPId.toString(), usertype: "200" }).read({
success: function(userResults) {
console.log('result', userResults[0]);
//Does not exist; return NOT FOUND as sp name!
if (userResults.length === 0) {
//This wroks fine and logs the expected result
console.log("customertickets/get: not SPname found", item.parsedjsondata.SPId);
//THIS DOES NOT WORK!
item.spname = "Service Provider Name Not Found";
}
//Record exists; return it
else {
//This wroks fine and logs the expected result
console.log("retrieved spname", JSON.parse(userResults[0].userjsondata).businessData.businessname.ar);
//THIS DOES NOT WORK!
item.spname = JSON.parse(userResults[0].userjsondata).businessData.businessname.ar;
}
}
});
}
//ActiveTicketsCounter
if (item.parsedjsondata.ticketStatus == "TicketStatus_ToBeAssigned"
|| item.parsedjsondata.ticketStatus == "TicketStatus_IsAssigned"
|| item.parsedjsondata.ticketStatus == "TicketStatus_InProgress"
|| item.parsedjsondata.ticketStatus == "TicketStatus_SPDisputed_CustomerNotReachable"
|| item.parsedjsondata.ticketStatus == "TicketStatus_SPDisputed_OutOfScope"
|| item.parsedjsondata.ticketStatus == "TicketStatus_SPDisputed_CustomerCanceled"
|| item.parsedjsondata.ticketStatus == "TicketStatus_SPDisputed_PriceDisagreement") {
activeTicketsCounter++;
}
//needCustomerRatingTicketCounter
if (item.parsedjsondata.ticketStatus == "TicketStatus_Completed_No_Customer_Rating") {
needCustomerRatingTicketCounter++;
}
//CompletedTicketsCounter
if (item.parsedjsondata.ticketStatus == "TicketStatus_Completed_And_Customer_Rated") {
completedTicketsCounter++;
}
//canceledTicketCounter
if (item.parsedjsondata.ticketStatus == "TicketStatus_CanceledByB8akAgent") {
canceledTicketCounter++;
}
//Testing: it works!
item.testing = "Testing Something!";
console.log("item.spname before push:", item.spname);
//pushing the found item to the list of results
filteredResults.push(item);
}
});
console.log("includeCounterData: " + includeCounterData);
if (includeCounterData == true) {
//After the loop, add the counters to the filteredresults to be returned
filteredResults.push({
activeTickets: activeTicketsCounter,
pendingCustomerRatingTickets: needCustomerRatingTicketCounter,
completedTickets: completedTicketsCounter,
canceledTickets: canceledTicketCounter
});
}
response.send(statusCodes.OK, filteredResults);
}
}
});
};
My main issue is that item.spname is never assigned a value and does not get returned in the response. I can see that the assigned value of item.spname which is JSON.parse(userResults[0].userjsondata).businessData.businessname.ar logs successfully in the AMS log but it does not get returned in the response.
The problem you have is that you're not waiting for the result of the many calls to
request.service.tables.getTable('User').where(...).read(...
to arrive before sending the response back to the client. Remember that almost everything in the node.js / JavaScript backend is asynchronous. When you call read on the User table, it won't wait for the result to arrive before executing the next statement - instead, it will queue the operation so that when the response is available, it will be executed.
To fix this you'll need to make all read calls to the users table, and only after you've got all the callbacks is when you can call response.send.