Add .is_active parameter to reactive expressions
Closed this issue · 3 comments
I would like to start using reactive expressions as I start to realize they are a powerful extension of pn.bind
.
One pattern I would often like to do is to disable components and/ or add loading indicators while a reactive expression is evaluating.
Context
I can do this manually by using another is_active
reactive expression.
import panel as pn
from time import sleep
pn.extension()
is_active = pn.rx(False)
submit = pn.widgets.Button(name="Start the wind turbine", loading=is_active, disabled=is_active)
def run(clicked):
is_active.rx.value = True
sleep(0.5)
print("done")
is_active.rx.value = False
rx_run = pn.rx(run)(submit)
# Figure out how to watch
pn.Column(submit, rx_run).servable()
is_active_rx.mp4
Please note that this example also experiences the issue in holoviz/panel#6426.
Request
Please make this pattern really simple to use by adding an .is_active
parameter to reactive expressions. Something like
rx_run.rx.is_active
that I can bind to.
Bonus question:
Instead of changing the value of a reactive expression two times as in the example. Is it possible to use a context manager similar to
with some_parameterized.param.update(value=False):
...
This already exists and has to be documented, specifically it's rx_run.rx.updating()
How would I combine .rx.updating()
with .watch
. I can't figure out how as .watch(...)
just returns None
. I.e. I don't get a handle on anything I can do .rx.updating()
on.
import panel as pn
from time import sleep
pn.extension()
submit = pn.widgets.Button(name="Start the wind turbine")
def run(clicked):
sleep(0.5)
print("done")
rx_run = pn.rx(submit).rx.watch(run)
submit.loading=submit.disabled=rx_run.rx.running()
# Figure out how to watch
pn.Column(submit).servable()
UPDATE
After some experimentation I found I need to break it down into 3 seperate steps.
import panel as pn
from time import sleep
pn.extension()
def run(clicked):
sleep(0.5)
print("done")
submit = pn.widgets.Button(name="Start the wind turbine", )
rx_run = pn.rx(submit)
submit.loading=submit.disabled=rx_run.rx.updating()
rx_run.rx.watch(run)
pn.Column(submit).servable()
Hmmm. My thinking was that I would like to disable the Button while the run function is running. Instead I can disable it while its clicked.
At the same time I am think whether the .rx
.watch
api is what you would expect. Why do you have to specify a function as argument? Why can't you just watch and execute the pipeline as in the below?
import panel as pn
from time import sleep
pn.extension()
is_active = pn.rx(False)
submit = pn.widgets.Button(name="Start the wind turbine", loading=is_active, disabled=is_active)
def run(clicked):
is_active.rx.value = True
sleep(0.5)
print("done")
is_active.rx.value = False
rx_run = pn.rx(run)(submit).rx.watch()
# Figure out how to watch
pn.Column(submit).servable()