-
Notifications
You must be signed in to change notification settings - Fork 108
Description
Hi,
I was trying to implement a lazy loading mechanism.
The data is defined as a reactive.Value, but is initially not initialized.
The data is loaded in a reactive Effect, that is fired when some other event is occurring (e.g. a button click, a nav item becoming active). The reactive Effect needs to check if the reactive Value is empty, and if so, it loads the required data and sets the reactive Value. Otherwise, it does nothing.
To get the current value of the reactive Value, I'm using a with isolate block. However, this block is raising a SilentException, and the next steps (the data load) never happens.
This is not limited to an isolate block. When used in an output function, the function stops when the empty reactive value is encountered.
Here's a simple example :
from shiny import *
app_ui = ui.page_fluid(
ui.h2("Lazy Load Demo"),
ui.input_action_button("in_load", "Load Data"),
ui.output_text_verbatim("out_data", placeholder=True),
ui.input_text("in_text", "Some text"),
ui.output_text_verbatim("out_text", placeholder=True),
)
def server(input, output, session):
data = reactive.Value()
# workaround:
# data = reactive.Value(False) or reactive.Value(pd.DataFrame())
@reactive.Effect
def load_data():
"""
Load data on demand. But only load it once.
If the data has been loaded before, do not reload
"""
req(input.in_load())
with reactive.isolate():
# check if data is loaded. Avoid dependency with the reactive value
# if using an initialized reactive.Value, the check may be different, e.g.
# loaded = data()
loaded = data() is not None
# This is never executed:
if loaded:
print("data already loaded, skipping")
else:
print("loading data, skipping")
data.set("Simulate")
@output
@render.text
def out_data():
"""
Also in the output function, calling the non-initialized reactive Value results in a SilentException.
"""
# req(data())
print("Rendering output")
# This is never executed:
print(data())
print("data printed")
return data()
@output
@render.text
def out_text():
return input.in_text()
app = App(app_ui, server)
I would expect that an empty reactive Value would simply return None, instead of raising a SilentException.
My workaround for the moment is to initialize the reactive Value with a value, such as False, or pd.DataFrame().
Shiny version : 0.2.9
Kind Regards,
Bart