I'm struggling a bit with Promise and async/await, i was sure i understood enough but i'm facing an issue that i don't understand. We are inside a discord bot command algorithm. This command can be executed for the user himself if no argument given, or for another user. The another user way requires to find it, by looking for it by nick/username or if it is a mention fetch it directly. But when it is about a mention, the operations execute in disorder and make the command fail.
I tried different ways, moving or framing the code parts, also surrounded the fetchMember call in an another async function and await inside on the fetchMember, but still the same result.
let targetMember;
const findTargetMember = (msg, targetArg) => {
return new Promise((resolve, reject) => {
if( msg.mentions.users.size>0 )
{
console.log("there are user mentions, taking the first one to get member", msg.mentions.users.first());
msg.guild.fetchMember(msg.mentions.users.first()).then(member => {
console.log("found member, resolving", member);
return resolve(member);
});
}
else
{
msg.guild.members.find(member => {
if( member.nickname && member.nickname.toLowerCase()===targetArg.toLowerCase() )
{
return resolve(member);
}
else if( member.user.username.toLowerCase()===targetArg.toLowerCase() )
{
return resolve(member);
}
});
}
return resolve(null);
});
};
(async () => {
targetMember = msg.member;
if( args[0] )
{
console.log("looking for another target member");
targetMember = await findTargetMember(msg, args[0]);
console.log("target member result :" + targetMember);
}
if( !targetMember )
{
return Replier.say(msg.channel, "Invalid member argument given", [msg.author]);
}
})();
console.log( targetMember );
The result in console is :
looking for another target member
there are user mentions, taking the first one to get member User {}
GuildMember {}
found member, resolving GuildMember {}
target member result : null
What i expected :
looking for another target member
there are user mentions, taking the first one to get member User {}
found member, resolving GuildMember {}
target member result : GuildMember {}
GuildMember {}
I would like to understand what i did wrong and missed.
EDIT : Tried it without async/await since it was said the problem came from that, so here another code version :
const findAnotherTargetMember = (msg, targetArg) => {
return new Promise((resolve, reject) => {
console.log("trying to find a target from an argument");
if( msg.mentions.users.size>0 )
{
console.log("there are user mentions, taking the first one", msg.mentions.users.first());
msg.guild.fetchMember(msg.mentions.users.first()).then(member => {
console.log("got member from it, resolving", member);
return resolve(member);
});
}
else
{
console.log("no user mentions, search by nick/username in guild members");
msg.guild.members.find(member => {
if( member.nickname && member.nickname.toLowerCase()===targetArg.toLowerCase() )
{
console.log("found by nickname, resolving", member);
return resolve(member);
}
else if( member.user.username.toLowerCase()===targetArg.toLowerCase() )
{
console.log("found by username, resolving", member);
return resolve(member);
}
});
}
console.log("no valid target found, resolving", null);
return resolve(null);
});
};
const defineTargetMember = (msg, args) => {
return new Promise((resolve, reject) => {
console.log("defining target");
let targetMember = msg.member;
console.log("set to message sender by default", targetMember);
if( args[0] )
{
console.log("argument found, trying to use it for get another target");
findAnotherTargetMember(msg, args[0]).then(anotherTargetMember => {
console.log("what came with this argument", anotherTargetMember);
if( anotherTargetMember===null )
{
Replier.say(msg.channel, "Invalid member argument given", [msg.author]);
}
console.log("resolving 2", anotherTargetMember);
return resolve(anotherTargetMember);
});
}
console.log("resolving 1", targetMember);
return resolve(targetMember);
});
};
defineTargetMember(msg, args).then(targetMember => {
if( targetMember!==null )
{
// .... code here
}
});
So there is no more problem with async variable value assign. Console output :
defining target
set to message sender by default GuildMember {}
argument found, trying to use it for get another target
trying to find a target from an argument
there are user mentions, taking the first one User {}
no valid target found, resolving null
resolving 1 GuildMember {}
got member from it, resolving GuildMember {}
what came with this argument null
resolving 2 null
What was expected :
defining target
set to message sender by default GuildMember {}
argument found, trying to use it for get another target
trying to find a target from an argument
there are user mentions, taking the first one User {}
got member from it, resolving GuildMember {}
resolving 1 GuildMember {}
what came with this argument GuildMember {}
I'm totally lost..