I have an app with a bunch of input fields. After any of the fields changes, an sequence of error check callbacks takes place which sometimes uses inputs from other fields. The combined number of errors for all fields ‘num_error’ is stored in a Store. Including latency, compute time etc, it can take a small amount of time before this update is finished. Let’s say 1 second for the sake of argument.
I also have a button called ‘compute_button’ which should do the actual calculations, but only if ‘num_error’ is zero.
The dcc.Input fields in the form use debounce=True, so that this error check function is not triggered after each keystroke, but only when the field loses focus.
Now, an edge case can happen and I am not sure about how to catch it. The fields are all filled out and num_error = 0. Imagine the user then starts entering an erroneous value in one of the fields, and causes it to defocus by clicking on the ‘compute_button’. I think this sets of two chains of events (in parallel?).
- n_click of compute_button gets incremented by one
- The input field with the bad value loses focus and the error check function starts. This will eventually discover the problem and change num_error to 1
@app.callback(Output("someoutput", "data"), #A Store which triggers the real computation function if changed
Input('compute_button', 'n_clicks'), #Button
Input("num_error", "data"), ...) #Number of errors in the inputs as recorded by Store
def computation(compute_button_n_clicks, num_error, ...):
#Do stuff if the trigger was compute_button_n_clicks
#But only if 'num_error = 0'
I had hoped that Dash would realize that it should wait executing function computation() until its second input num_error() got updated. But that is not what happens. The function triggered by the button click will still think num_error = 0. The function incorrectly thinks there are no errors and will continue with the execution of the function. Sometime later the function will be triggered a second time, when num_error finally got updated from 0 to 1.
I guess this means that the user click indeed sets of two parallel callbacks as listed above, both unaware of each other? Is there a way I can ask the Dash API if there are ongoing parallel callbacks? In that case I could perhaps use logic to catch the situation described above.
(I guess I could make one mega-function which takes all inputs, performs all the error checks and eventually performs the computation if all is well. But this would make the code a lot harder to maintain and a lot messier. I would really like to avoid that situation)