Reputation: 213
I have the following code and am attempting to make a Turntable bot using node.js. this piece of code says when a user types "q+" we have to make sure its not already on the queue, that its not already DJing, and if it meets those 2 requirements, add them to the queue. Otherwise if it doesnt meet one of those first 2 criteria, tell the user and do not touch the queue.
My problem is the "isCurrentDJ(userId)". When I pass a userId through that function, the function gives me the correct answer. However the function ALWAYS passes back "false" even when the answer is "true" and the console.log() function within the isCurrentDJ(userId) function proves so.
I am not the most js-savvy person, so I think this may be a variable scope issue. But I am really not sure and have been struggling with it for hours! Any help would be greatly appreciated. Thanks!
// When someone speaks, listen to see if it is one of the q commands
bot.on('speak', function (data) {
var name = data.name;
var text = data.text;
var userId = data.userid;
// q+ :: Add to Queue
if (text.match(/^q\+$/)) {
//Index is the position in the queue that this person's name is found.
//If its not found, -1 is returned.
var index = queue.indexOf(name);
//Function to determine if the user is currently a DJ
function isCurrentDJ(user_id, callback){
bot.roomInfo(false, function (data) {
var djList = data.room.metadata.djs;
for (i = 0; i < djList.length; i++){
if (djList[i] == user_id){
console.log('recognized as a DJ'); //Consistently printed!
callback(true);
}
}
callback(false);
});
}
isCurrentDJ(userId, function(isDJ) {
//If the user is already in the queue
if(index > -1){
//Tell them they are already in there
bot.speak('You are already on the list');
} else if(isDJ){
//Otherwise if they are already a DJ tell them that
bot.speak('You are already a DJ, '+name);
}else{
//Otherise if they are not in the queue add user to end of queue
queue.push(name);
//Tell them about it and the updated q
bot.speak(name+' has been added to queue.');
}
});
}
Upvotes: 0
Views: 96
Reputation: 14881
Your problem is that bot.roomInfo
is an asynchronous function.
When you call it, it immediately returns and currDJ
is still false. A little while later, the callback (function(data) {...
) is called. Most of node.js's API are async so that your code never blocks.
Here's how you should rewrite your code:
// When someone speaks, listen to see if it is one of the q commands
bot.on('speak', function (data) {
var name = data.name;
var text = data.text;
var userId = data.userid;
// q+ :: Add to Queue
if (text.match(/^q\+$/)) {
//Index is the position in the queue that this person's name is found.
//If its not found, -1 is returned.
var index = queue.indexOf(name);
//Function to determine if the user is currently a DJ
function testCurrentDJ(user_id, cb){
bot.roomInfo(false, function (data) {
var djList = data.room.metadata.djs;
for (i = 0; i < djList.length; i++){
if (djList[i] == user_id){
console.log('recognized as a DJ'); //Consistently printed!
return cb(true);
}
}
cb(false);
});
}
//If the user is already in the queue
if(index > -1){
//Tell them they are already in there
bot.speak('You are already on the list');
return;
}
testCurrentDJ(userId, function(isDJ) {
//Otherwise if they are already a DJ tell them that
if(isDJ) {
bot.speak('You are already a DJ, '+name);
} else {
//Otherise if they are not in the queue add user to end of queue
queue.push(name);
//Tell them about it and the updated q
bot.speak(name+' has been added to queue. Is Current DJ? '+isDJ);
}
})
}
I've just updated your code to show you the basic idea. In node.js's API, the first argument of callbacks is usually an error object that is null if everything went fine.
Upvotes: 1
Reputation: 57729
Is bot.roomInfo
perhaps an asynchronous function? If so the value of currDJ
will be set to true, but too late because you've already returned it. You can no operate on the value of currDJ
untill that callback is called.
How familiar are you with the concept of asynchronous functions?
Upvotes: 0