Hello everyone!
Long time fan, first time writer.
I have a question regarding pattern matching callbacks together with Partial Updates.
To illustrate the problem, I adapted the example from Partial Property Updates | Dash for Python Documentation | Plotly to also add a new output item for each dropdown and connect the callbacks using MATCH
instead of ALL
:
from dash import Dash, dcc, html, Input, Output, MATCH, Patch, callback, ctx
app = Dash(__name__, suppress_callback_exceptions=True)
app.layout = html.Div(
[
html.Button("Add Filter", id="add-filter-2", n_clicks=0),
html.Div(id="dropdown-container-2", children=[]),
html.Div(id="dropdown-container-output-2"),
]
)
@callback(
Output("dropdown-container-2", "children"),
Output("dropdown-container-output-2", "children"),
Input("add-filter-2", "n_clicks"),
)
def display_dropdowns(n_clicks):
patched_children = Patch()
new_dropdown = dcc.Dropdown(
["NYC", "MTL", "LA", "TOKYO"],
id={"type": "filter-dropdown-2", "index": n_clicks},
)
patched_children.append(new_dropdown)
patched_outputs = Patch()
new_output = html.Div(
id={"type": "generated-output", "index": n_clicks},
)
patched_outputs.append(new_output)
return patched_children, patched_outputs
@callback(
Output({"type": "generated-output", "index": MATCH}, "children"),
Input({"type": "filter-dropdown-2", "index": MATCH}, "value"),
)
def display_output(value):
print(ctx.triggered_id)
return html.Div("Dropdown {} = {}".format(value, value))
if __name__ == "__main__":
app.run(debug=True)
Running this and adding new dropdowns results in triggering all callbacks every time a new item is appended.
E.g. the output of the ctx.triggered_id
print statements grows for every added item:
{'index': 0, 'type': 'filter-dropdown-2'}
{'index': 1, 'type': 'filter-dropdown-2'}
{'index': 2, 'type': 'filter-dropdown-2'}
{'index': 3, 'type': 'filter-dropdown-2'}
So it seems that whenever a partial update appends a new item, all patern-matching callbacks are triggered, whereas all existing ones did not change.
Is there any way to prevent this?
Thanks in advance
Andre