h2oai / wave

Realtime Web Apps and Dashboards for Python and R
https://wave.h2o.ai
Apache License 2.0
3.9k stars 323 forks source link

`run_on` stops routing to `#foo` after a textbox `trigger=True` #2216

Open petergaultney opened 6 months ago

petergaultney commented 6 months ago

Wave SDK Version, OS

1.0.0, Mac

Actual behavior

calling await run_on(q) returns False and fails to route if __wave_submission_name__ is not #.

Expected behavior

This is undocumented behavior, and since the examples on https://wave.h2o.ai/docs/routing#hash-route-switching do not suggest that you should not route unconditionally based on the value of q.args['#'], it seems surprising to me that run_on is unwilling to route regardless of the value of __wave_submission_name__.

Further the docs strongly suggest a different behavior when they say "this function will be called when q.args['#'] == 'menu' - this is really not true, because it will only be called if that is true and the submission name is also #.

Steps To Reproduce

Write a simple app where a textbox created when routed to #hello has trigger=True, and expect that to route back to a handler decorated with @on('#hello'). It will only route the first time; after that, it will no longer find that route.

Further context

I'm trying to establish that I can do reasonably performant server-side validation of client input. I love how y'all have implemented debounce for input, for instance, so if I type a whole sentence, it doesn't send any events to the backend until I pause typing.

Once I get that event, and as long as I'm still on the "form-input" route, I want to be able to keep the state of the Submit button either enabled or disabled based on my server-side validation. It seemed like the right way to do this was to keep routing back to the same handler for that form. Apparently, however, that's not really possible with run_on - instead, I have to notice that run_on failed to route, and then do my own routing based on q.args['#'].

In the end, I can probably just build my own version of run_on. But it would be nice to be able to use the official one and just keep handling the same route that I'm already on.

mturoci commented 6 months ago

the docs strongly suggest a different behavior when they say "this function will be called when q.args['#'] == 'menu' - this is really not true, because it will only be called if that is true and the submission name is also #.

This needs correction, yes.run_on handles only the "latest user interaction" so that means if user navigates to #hello, it calls #hello handler. If user fills textbox with trigger=True, it only calls the corresponding textbox handler. This means you either need to split validation into separate @on functions or write your own special routing to match your exact needs.