[Feature Request] simplified syntax when several Inputs can trigger a callback #1054
Description
With Dash, it is not possible to have multiple callbacks modifying a given Output
(see #153). The reason is that if this were possible, one could imagine having several callback sharing as Input the same property and modifying the same Output
, and one could not decide which one to fire.
Therefore, the solution is to group all the inputs in a big callback, and since a different behaviour is often expected depending on which Input
fired the callback, one ends up with a quite verbose syntax such as
ctx = dash.callback_context
if not ctx.triggered:
button_id = 'No clicks yet'
else:
button_id = ctx.triggered[0]['prop_id'].split('.')[0]
if button_id == 'button1':
...
elif ....
@alexcjohnson suggested that we could introduce a Trigger
object which would be a variant of Input
. It would be called as Trigger("button1", "n_clicks")
and would feed the callback True (if that was the trigger) or False. Therefore we could write callbacks like
@app.callback(...
)
def update(arg1_changed, arg2_changed)
if arg1_changed:
return update_output_arg1(...)
elif arg2_changed:
return update_output1_arg2(...)
As a side note it would be great to update our documentation to encourage more breaking callbacks into smaller functions like above, so that a multiple-input callback is more a router.
A variant of the Trigger
would be to have a tuple (triggered_bool, prop_value)
so that one would write arg1_changed[0]
for the bool and arg1_changed[1]
for the value. (Therefore we would not need to use callback_context
at all).