Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async callback in Element.on() can lead to IndexError in slot stack #285

Closed
2 tasks done
falkoschindler opened this issue Jan 23, 2023 Discussed in #280 · 4 comments
Closed
2 tasks done

Async callback in Element.on() can lead to IndexError in slot stack #285

falkoschindler opened this issue Jan 23, 2023 Discussed in #280 · 4 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@falkoschindler
Copy link
Contributor

falkoschindler commented Jan 23, 2023

Discussed in #280

Here is a minimal reproduction. The first button works as expected, the second one doesn't.

async def handle_click():
    await asyncio.sleep(0.1)
    ui.notify('clicked')

ui.button('Works', on_click=handle_click)
ui.button('Fails').on('click', handle_click)
  • support async callbacks in Element.on()
  • while we are here: make Element available as ui.element
@falkoschindler falkoschindler self-assigned this Jan 23, 2023
@falkoschindler falkoschindler added enhancement New feature or request bug Something isn't working and removed enhancement New feature or request labels Jan 23, 2023
@falkoschindler falkoschindler added this to the v1.1.4 milestone Jan 23, 2023
@SebastienDorgan
Copy link

Hi @falkoschindler,
As I really wanted this to work I have created a simple work around that is, I hope, interesting to share

import asyncio
from nicegui import ui, Client
from nicegui.events import ClickEventArguments, handle_event
@ui.page('/')
async def main_page(client: Client):
    async def handle_click():
        await asyncio.sleep(0.1)
        ui.notify('clicked')

    ui.button('Works', on_click=handle_click)
    button = ui.button("Works with effort")
    button.on("click", lambda _: handle_event(handle_click, ClickEventArguments(sender=button, client=button.client)))
    ui.button('Fails').on('click', lambda _: handle_click())

ui.run(show=False)

@falkoschindler
Copy link
Contributor Author

falkoschindler commented Jan 26, 2023

Thanks for sharing, @SebastienDorgan! That's a great workaround.

And that's basically what needs to be done to fix .on() in NiceGUI. We just have to check where to put the additional call to handle_event so that "normal" event handlers like on_click don't call it twice internally. So we probably have to move the handle_event call out of UI elements like button and into .on() in the element base class.

@falkoschindler
Copy link
Contributor Author

I created PR #305 which should solve this issue.

@rodja
Copy link
Member

rodja commented Jan 28, 2023

I've just merged the code.

@rodja rodja closed this as completed Jan 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants