'How can we store the value of a Modal in Pycord (2.x) in a method/function and then return it?

class title_input_modal(Modal):
    def __init__(self):
        super().__init__("Audio Title Input")

        self.add_item(InputText(label = "Audio Title", style = discord.InputTextStyle.short))

    async def callback(self, interaction: discord.Interaction):
        
        val = self.children[0].value
        await interaction.response.send_message(val)

How can I make a method and store the value of the response? If I try accessing title_input_modal.children[0] from another cog's class method, this error pops up:-

Ignoring exception in view <View timeout=180.0 children=1> for item <Button style=<ButtonStyle.primary: 1> url=None disabled=False label='Play' emoji=<PartialEmoji animated=False name='▶️' id=None> row=None>:
Traceback (most recent call last):
  File "C:\Users\Chinmay Krishna\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\ui\view.py", line 371, in _scheduled_task
    await item.callback(interaction)
  File "d:\Programming\python\intellij\intellij_python\AxC-777-Music\no_upload.py", line 137, in play_button_callback
    print(title_input_modal.children[0].value)
AttributeError: type object 'title_input_modal' has no attribute 'children'
Ignoring exception in view <View timeout=180.0 children=1> for item <Button style=<ButtonStyle.primary: 1> url=None disabled=False label='Play' emoji=<PartialEmoji animated=False name='▶️' id=None> row=None>:
Traceback (most recent call last):
  File "C:\Users\Chinmay Krishna\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\discord\ui\view.py", line 371, in _scheduled_task
    await item.callback(interaction)
  File "d:\Programming\python\intellij\intellij_python\AxC-777-Music\no_upload.py", line 137, in play_button_callback
    print(title_input_modal.children[0].value)
AttributeError: type object 'title_input_modal' has no attribute 'children'


Solution 1:[1]

You can store the value in your class as a property and access it once the modal has been dismissed. To do so you will have to modify your class like this.

class title_input_modal(Modal):
    def __init__(self):
        super().__init__("Audio Title Input")
        
        #
        self.val = None

        self.add_item(InputText(label = "Audio Title", style = discord.InputTextStyle.short))

    async def callback(self, interaction: discord.Interaction):
        
        self.val = self.children[0].value
        await interaction.response.send_message(val)
        self.stop()

Then from where you call your modal, you will have to initialise it like this so that you can then access its properties

title_modal = title_input_modal()
await ...send_modal(title_modal)
await title_modal.wait()
print(title_modal.val)

Without the stop and wait methods, your bot won't wait for the modal interaction to be over, so you won't be able to access the value from the user.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shoni Fari