Issue with "custom" autocomplete

I will be sending the relevant parts of my code, I'm kind of new to this so please be patient, I would like the command to load the user's options based on their inventory in mongoose, the autocomplete options don't load while the user tries to write in the item field, however the item is correctly used if the user writes the exact name (caps sensitive). I would like the autocomplete suggestions to be the user's available items, I have looked for the autocomplete in discord,js but I didn't quite understand how it should work for my case.
14 Replies
d.js toolkit
d.js toolkit3w ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button! - Marked as resolved by OP
Flotty
FlottyOP3w ago
v22.13.1, it won't show the discord.js when running the command you sent tho
async autocomplete(interaction) {
const focusedOption = interaction.options.getFocused(true);

if (focusedOption.name === 'item') {
const user = interaction.user;
const inventory = await InventoryModel.findOne({ userId: user.id });

if (!inventory) {
return interaction.respond([]);
}

const usableItems = inventory.items.filter(item =>
Object.keys(items.usables).includes(item.itemId) && item.quantity > 0
);

const suggestions = usableItems.map(item => ({
name: item.itemId,
value: item.itemId
}));

await interaction.respond(suggestions);
}
}
};
async autocomplete(interaction) {
const focusedOption = interaction.options.getFocused(true);

if (focusedOption.name === 'item') {
const user = interaction.user;
const inventory = await InventoryModel.findOne({ userId: user.id });

if (!inventory) {
return interaction.respond([]);
}

const usableItems = inventory.items.filter(item =>
Object.keys(items.usables).includes(item.itemId) && item.quantity > 0
);

const suggestions = usableItems.map(item => ({
name: item.itemId,
value: item.itemId
}));

await interaction.respond(suggestions);
}
}
};
NyR
NyR3w ago
Check if you are getting any errors in the console. Autocomplete needs to be responded within 3 sec, and since you are doing async operations (db call) it maybe taking longer. Another cause would be if you suggestions exceeds the 25 choices limits. In either case, an error would tell you
Flotty
FlottyOP3w ago
This is what I get, no error in the console though, also the total of items is about 6 so it shouldn't exceed the maximum number
No description
d.js docs
d.js docs3w ago
tag suggestion for @Flotty: If you aren't getting any errors, try to place console.log checkpoints throughout your code to find out where execution stops. - Once you do, log relevant values and if-conditions - More sophisticated debugging methods are breakpoints and runtime inspections: learn more
Flotty
FlottyOP3w ago
Wait I'll send the full command (it's actually two different commands with the same issue but I assume if I fix one I should be able to fix the other)
module.exports = {
data: new SlashCommandBuilder()
.setName('adminitemgive')
.setDescription('Give an item to a user')
.addUserOption(option =>
option.setName('user')
.setDescription('User to give the item to')
.setRequired(true)
)
.addStringOption(option =>
option.setName('item')
.setDescription('Item to give')
.setRequired(true)
.setAutocomplete(true)
)
.addIntegerOption(option =>
option.setName('quantity')
.setDescription('Quantity of the item to give')
.setRequired(true)
.setMinValue(1)
.setMaxValue(100)
),

async execute(interaction) {
if (interaction.user.id !== YOUR_USER_ID) {
return interaction.reply({ content: 'You do not have permission to use this command.', flags: 64 });
}

const user = interaction.options.getUser('user');
const itemId = interaction.options.getString('item');
const quantity = interaction.options.getInteger('quantity');

let inventory = await InventoryModel.findOne({ userId: user.id });
if (!inventory) {
inventory = new InventoryModel({ userId: user.id, items: [], equippedRunes: { playstyle: {}, elemental: [] } });
await inventory.save();
}

const allItems = [
...items.runes.playstyle,
...items.runes.elemental,
...Object.keys(items.usables),
];

const item = allItems.find(i => i.toLowerCase() === itemId.toLowerCase());
if (!item) {
return interaction.reply({ content: 'Item not found.', flags: 64 });
}

await inventory.addItem(itemId, quantity);
return interaction.reply({ content: `${quantity}x ${itemId} have been given to ${user.username}.`, flags: 64 });
},
module.exports = {
data: new SlashCommandBuilder()
.setName('adminitemgive')
.setDescription('Give an item to a user')
.addUserOption(option =>
option.setName('user')
.setDescription('User to give the item to')
.setRequired(true)
)
.addStringOption(option =>
option.setName('item')
.setDescription('Item to give')
.setRequired(true)
.setAutocomplete(true)
)
.addIntegerOption(option =>
option.setName('quantity')
.setDescription('Quantity of the item to give')
.setRequired(true)
.setMinValue(1)
.setMaxValue(100)
),

async execute(interaction) {
if (interaction.user.id !== YOUR_USER_ID) {
return interaction.reply({ content: 'You do not have permission to use this command.', flags: 64 });
}

const user = interaction.options.getUser('user');
const itemId = interaction.options.getString('item');
const quantity = interaction.options.getInteger('quantity');

let inventory = await InventoryModel.findOne({ userId: user.id });
if (!inventory) {
inventory = new InventoryModel({ userId: user.id, items: [], equippedRunes: { playstyle: {}, elemental: [] } });
await inventory.save();
}

const allItems = [
...items.runes.playstyle,
...items.runes.elemental,
...Object.keys(items.usables),
];

const item = allItems.find(i => i.toLowerCase() === itemId.toLowerCase());
if (!item) {
return interaction.reply({ content: 'Item not found.', flags: 64 });
}

await inventory.addItem(itemId, quantity);
return interaction.reply({ content: `${quantity}x ${itemId} have been given to ${user.username}.`, flags: 64 });
},
async autocomplete(interaction) {
const focusedOption = interaction.options.getFocused(true);
const allItems = [
...items.runes.playstyle,
...items.runes.elemental,
...Object.keys(items.usables),
];

let choices = allItems.filter(item => item.toLowerCase().includes(focusedOption.value.toLowerCase()));

await interaction.respond(
choices.map(choice => ({ name: choice, value: choice }))
);
}
}
async autocomplete(interaction) {
const focusedOption = interaction.options.getFocused(true);
const allItems = [
...items.runes.playstyle,
...items.runes.elemental,
...Object.keys(items.usables),
];

let choices = allItems.filter(item => item.toLowerCase().includes(focusedOption.value.toLowerCase()));

await interaction.respond(
choices.map(choice => ({ name: choice, value: choice }))
);
}
}
Had to split it into 2 parts because I don't have nitro for longer messages lmao
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
Flotty
FlottyOP3w ago
:pikaOh: I don't get what you mean
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
Flotty
FlottyOP3w ago
I had copied the command handler from a YouTube video, would I need to make a new file with the autocomplete handler or just add something in the old file?
d.js docs
d.js docs3w ago
:guide: Slash Commands: Autocomplete read more
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View
Flotty
FlottyOP3w ago
Tyvm :blobreachReverse: Omg it worked ty @gwapes
Unknown User
Unknown User3w ago
Message Not Public
Sign In & Join Server To View

Did you find this page helpful?