Autocomplete - option.match is not a function
Trying to use auto complete. Getting a weird error:
Here is the code. Below the code is what is being returned by the case 'crop'. This same filter works just fine in discord.js directly, but sapphire doesn't seem to like it.
2024-05-15 03:28:54 - ERROR - Encountered error on event listener "CorePossibleAutocompleteInteraction" for event "possibleAutocompleteInteraction" at path "::virtual::" TypeError: option.match is not a function
2024-05-15 03:28:54 - ERROR - at Object.ok (/home/phil/foc-bot/node_modules/@sapphire/framework/dist/cjs/lib/structures/InteractionHandlerStore.cjs:26:18)
2024-05-15 03:28:54 - ERROR - at _ResultOk.match (/home/phil/foc-bot/node_modules/@sapphire/result/dist/cjs/index.cjs:151:21)
2024-05-15 03:28:54 - ERROR - at _InteractionHandlerStore.run (/home/phil/foc-bot/node_modules/@sapphire/framework/dist/cjs/lib/structures/InteractionHandlerStore.cjs:23:16)
2024-05-15 03:28:54 - ERROR - at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
2024-05-15 03:28:54 - ERROR - at async _CoreListener.run (/home/phil/foc-bot/node_modules/@sapphire/framework/dist/cjs/listeners/application-commands/CorePossibleAutocompleteInteraction.cjs:34:5)
2024-05-15 03:28:54 - ERROR - at async Object.fromAsync (/home/phil/foc-bot/node_modules/@sapphire/result/dist/cjs/index.cjs:619:22)
2024-05-15 03:28:54 - ERROR - at async _CoreListener._run (/home/phil/foc-bot/node_modules/@sapphire/framework/dist/cjs/lib/structures/Listener.cjs:27:22)
2024-05-15 03:28:54 - ERROR - Encountered error on event listener "CorePossibleAutocompleteInteraction" for event "possibleAutocompleteInteraction" at path "::virtual::" TypeError: option.match is not a function
2024-05-15 03:28:54 - ERROR - at Object.ok (/home/phil/foc-bot/node_modules/@sapphire/framework/dist/cjs/lib/structures/InteractionHandlerStore.cjs:26:18)
2024-05-15 03:28:54 - ERROR - at _ResultOk.match (/home/phil/foc-bot/node_modules/@sapphire/result/dist/cjs/index.cjs:151:21)
2024-05-15 03:28:54 - ERROR - at _InteractionHandlerStore.run (/home/phil/foc-bot/node_modules/@sapphire/framework/dist/cjs/lib/structures/InteractionHandlerStore.cjs:23:16)
2024-05-15 03:28:54 - ERROR - at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
2024-05-15 03:28:54 - ERROR - at async _CoreListener.run (/home/phil/foc-bot/node_modules/@sapphire/framework/dist/cjs/listeners/application-commands/CorePossibleAutocompleteInteraction.cjs:34:5)
2024-05-15 03:28:54 - ERROR - at async Object.fromAsync (/home/phil/foc-bot/node_modules/@sapphire/result/dist/cjs/index.cjs:619:22)
2024-05-15 03:28:54 - ERROR - at async _CoreListener._run (/home/phil/foc-bot/node_modules/@sapphire/framework/dist/cjs/lib/structures/Listener.cjs:27:22)
import _ from 'lodash';
import { InteractionHandler, InteractionHandlerTypes } from '@sapphire/framework';
import type { AutocompleteInteraction } from 'discord.js';
import crops from '../config/crops.json';
export class AutocompleteHandler extends InteractionHandler {
public constructor(ctx: InteractionHandler.LoaderContext, options: InteractionHandler.Options) {
super(ctx, {
...options,
interactionHandlerType: InteractionHandlerTypes.Autocomplete
});
}
public override async run(interaction: AutocompleteInteraction, result: InteractionHandler.ParseResult<this>) {
return interaction.respond(result);
}
public override async parse(interaction: AutocompleteInteraction) {
if (interaction.commandName !== 'crop') return this.none();
const focusedOption = interaction.options.getFocused(true);
// Ensure that the option name is one that can be autocompleted, or return none if not.
switch (focusedOption.name) {
case 'crop': {
let choices;
choices = _.keys(_.mapKeys(crops, (value, key) => { return `${value}|${key}` }));
const filtered = choices.filter(choice => choice.toLocaleLowerCase().includes(focusedOption.value.toLowerCase())).slice(0,25);
return filtered.map(choice => ({ name: _.split(choice,'|')[0], value: _.split(choice,'|')[1] }));
}
default:
return this.none();
}
}
}
import _ from 'lodash';
import { InteractionHandler, InteractionHandlerTypes } from '@sapphire/framework';
import type { AutocompleteInteraction } from 'discord.js';
import crops from '../config/crops.json';
export class AutocompleteHandler extends InteractionHandler {
public constructor(ctx: InteractionHandler.LoaderContext, options: InteractionHandler.Options) {
super(ctx, {
...options,
interactionHandlerType: InteractionHandlerTypes.Autocomplete
});
}
public override async run(interaction: AutocompleteInteraction, result: InteractionHandler.ParseResult<this>) {
return interaction.respond(result);
}
public override async parse(interaction: AutocompleteInteraction) {
if (interaction.commandName !== 'crop') return this.none();
const focusedOption = interaction.options.getFocused(true);
// Ensure that the option name is one that can be autocompleted, or return none if not.
switch (focusedOption.name) {
case 'crop': {
let choices;
choices = _.keys(_.mapKeys(crops, (value, key) => { return `${value}|${key}` }));
const filtered = choices.filter(choice => choice.toLocaleLowerCase().includes(focusedOption.value.toLowerCase())).slice(0,25);
return filtered.map(choice => ({ name: _.split(choice,'|')[0], value: _.split(choice,'|')[1] }));
}
default:
return this.none();
}
}
}
[
{ name: 'Egg', value: 'EGG' },
{ name: 'Wool', value: 'WOOL' },
{ name: 'Milk', value: 'MILK' },
{ name: 'Barley', value: 'BARLEY' },
{ name: 'Bourbon', value: 'BOURBON' },
{ name: 'Canola', value: 'CANOLA' },
{ name: 'Cotton', value: 'COTTON' },
{ name: 'Grape', value: 'GRAPE' },
{ name: 'Corn', value: 'MAIZE' },
{ name: 'Oat', value: 'OAT' },
{ name: 'Oilseed Radish', value: 'OILSEEDRADISH' },
{ name: 'Olive', value: 'OLIVE' },
{ name: 'Poplar', value: 'POPLAR' },
{ name: 'Potato', value: 'POTATO' },
{ name: 'Sorghum', value: 'SORGHUM' },
{ name: 'Soybean', value: 'SOYBEAN' },
{ name: 'Sugarbeet', value: 'SUGARBEET' },
{ name: 'Sugarbeet (Cut)', value: 'SUGARBEET_CUT' },
{ name: 'Sugarcane', value: 'SUGARCANE' },
{ name: 'Sunflower', value: 'SUNFLOWER' },
{ name: 'Wheat', value: 'WHEAT' },
{ name: 'Digestate', value: 'DIGESTATE' },
{ name: 'Fertilizer', value: 'FERTILIZER' },
{ name: 'Herbicide', value: 'HERBICIDE' },
{ name: 'Lime', value: 'LIME' }
]
[
{ name: 'Egg', value: 'EGG' },
{ name: 'Wool', value: 'WOOL' },
{ name: 'Milk', value: 'MILK' },
{ name: 'Barley', value: 'BARLEY' },
{ name: 'Bourbon', value: 'BOURBON' },
{ name: 'Canola', value: 'CANOLA' },
{ name: 'Cotton', value: 'COTTON' },
{ name: 'Grape', value: 'GRAPE' },
{ name: 'Corn', value: 'MAIZE' },
{ name: 'Oat', value: 'OAT' },
{ name: 'Oilseed Radish', value: 'OILSEEDRADISH' },
{ name: 'Olive', value: 'OLIVE' },
{ name: 'Poplar', value: 'POPLAR' },
{ name: 'Potato', value: 'POTATO' },
{ name: 'Sorghum', value: 'SORGHUM' },
{ name: 'Soybean', value: 'SOYBEAN' },
{ name: 'Sugarbeet', value: 'SUGARBEET' },
{ name: 'Sugarbeet (Cut)', value: 'SUGARBEET_CUT' },
{ name: 'Sugarcane', value: 'SUGARCANE' },
{ name: 'Sunflower', value: 'SUNFLOWER' },
{ name: 'Wheat', value: 'WHEAT' },
{ name: 'Digestate', value: 'DIGESTATE' },
{ name: 'Fertilizer', value: 'FERTILIZER' },
{ name: 'Herbicide', value: 'HERBICIDE' },
{ name: 'Lime', value: 'LIME' }
]
Solution:Jump to solution
Instead of returning filtered.map, wrap that in this.some just like how you return this.none
2 Replies
Solution
Instead of returning filtered.map, wrap that in this.some just like how you return this.none
Odd. Thanks. I've not gotten a chance to try it yet because I've properly pissed off typescript, but I'll go ahead and marks this as solved.