Creating dropdown menu from API response in Discord bot

I’m developing a Discord bot that presents a form to users and generates a dropdown based on their entries. The flow is this: the user fills out a form, I handle their input to retrieve data from an API (which typically returns a maximum of 20 items), and then I aim to display a selection menu with those options.

However, I keep encountering this error:

for player in raid_members['name']]
           ^^^^^^^^^^^^^
NameError: name 'raid_members' is not defined

Here is my current code:

class DataInput(discord.ui.Modal, title="Enter Details"):
    user_input = discord.ui.TextInput(label="Code")    
    async def on_submit(self, interaction: discord.Interaction):
        input_value = self.user_input.value
        token = fetch_auth_token()
        save_token(token)
        parsed_data = api_handler.get_player_data(input_value)
        global raid_members
        raid_members = parsed_data['playerList']
        for player in raid_members:
            print(player)
        await interaction.response.send_message(view=PlayerSelector())

class PlayerSelector(discord.ui.View):
    @discord.ui.select(
        placeholder="Pick a player",
        min_values=0, max_values=20,
        options=[discord.SelectOption
            (label=player['name'], value=player['name'])
                for player in raid_members['name']]
    )
    async def select_player(self, interaction: discord.Interaction, select: discord.ui.Select):
        chosen_values = select.values
        print(chosen_values)
        await interaction.response.send_message(chosen_values)

I have tried utilizing global variables, but it still doesn’t resolve the problem. The variable appears to be undefined when the selection menu attempts to access it. How can I rectify this issue?

Globals won’t work here - the decorator runs when the class is defined, not at runtime. You need to create the select options dynamically. Move the options creation inside a method or override the view’s callback to build options when they’re actually needed instead of in the decorator.

Found the issue - you’re trying to access raid_members['name'] when raid_members is already a list. Just loop through it directly with for player in raid_members instead.

The bigger problem is you’re creating PlayerSelector before the data’s even available. I ran into this same thing and fixed it by building the select component after getting the API response. Override PlayerSelector’s __init__ method to take the player data as a parameter, then construct your options there. Pass the parsed data directly when you create the PlayerSelector instance.

The issue arises because the PlayerSelector class is being instantiated before the raid_members variable is defined. Even if you use global variables, the select options are created when the class is defined, not when it is used. I had a similar challenge with a bot dealing with API data. To fix this, you should consider passing the player data directly to the PlayerSelector constructor or creating the select options inside the view’s __init__ method. This ensures that the data is available when the dropdown is built, eliminating the scope issues related to globals.