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
dash_extensions, but for some reason
Outputs 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
download callback, the button and dropdown are disabled properly. But if in contrast I leave these
Outputs 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?
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.