Skip to content

[Feature Request] simplified syntax when several Inputs can trigger a callback  #1054

Closed
@emmanuelle

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).

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions