Hello everybody!
So, I’ve been trying to make one of the most basic things you may imagine doing on your website – user clicks on a button, some computations go on, disable the button and when the result is over turn it on again. Plain and simple, but put me into the pit of despair – moreover, I bet I’ll be short of a handful of hair after this task.
I am trying to use the MultiplexerTransform
from dash_extensions
, but for some reason Output
s of callbacks are not being updated, even though the corresponding callbacks ARE getting fired up for sure.
Here is a little demonstration:
from time import sleep
from dash_extensions.enrich import (
DashProxy,
Input,
Output,
State,
MultiplexerTransform,
NoOutputTransform,
html,
dcc,
callback_context,
)
app = DashProxy(transforms=[
MultiplexerTransform(),
])
button = html.Button('Button', id='download_button')
dropdown = dcc.Dropdown(['One', 'Two', 'Three'], 'One', id = 'choise_drop')
dummy = dcc.Store(id='dummy')
trigger = dcc.Store(id='trigger')
app.layout = html.Div(
children=[
button,
dropdown,
dummy,
trigger,
],
id='main',
)
@app.callback(
Output('dummy', 'data'),
Input('choise_drop', 'value'),
prevent_initial_call=True,
)
def select(sel_opt):
print('GRAPH CHOISE')
@app.callback(
Output('choise_drop', 'disabled'),
Output('download_button', 'disabled'),
Input('trigger', 'data'),
prevent_initial_call=True,
)
def download(trig_data):
print('TRIGGER')
sleep(5)
return False, False
@app.callback(
Output('choise_drop', 'disabled'),
Output('download_button', 'disabled'),
Output('trigger', 'data'),
Input('download_button', 'n_clicks'),
State('choise_drop', 'value'),
prevent_initial_call=True,
)
def download_button(n_clicks, sel_opt):
print('BUTTON')
return True, True, True
if __name__ == '__main__':
app.run_server(debug=True)
Here, if I delete the Output
s of download
callback, the button and dropdown are disabled properly. But if in contrast I leave these Output
s only in this callback and delete them from the download_button
nothing works, similarly to the full solution.
Am I doing something wrong or it is just a bug?
PS.
Yes, I’ve been trying to make this happen without extensions via dedicated callback that would check whether that was a button fired, or a State
triggered by the button after the computation is over (the trick with context like one good fellah described here), but the order of callbacks is not guaranteed, so I was left in the situation where buttons were not enabled at all.