I am trying to understand something in my application callback flow.
I am using pure Dash (2.7.0) and dash-extensions (0.1.8) @Emil
When i have an in Input updating an Output of a different component, my callbacks get triggered everytime i update the children of my parent component. In my example I have a button that adds 2 elements to the UI each time i click it. When I click the new button added, I expect the corresponding Output to update (ONLY when I click it) but it also gets fired everytime I add more buttons
In the screenshot below you can see that I only clicked the add button, but the trigger for each child button gets fired each time. I would only expect the text next to each button to be updated when it is clicked.
Can anyone suggest a workaround/hack or some kind of change I can make to get this to work. The code is written to mock part of my real code so I cant completely rewrite it all
from dash import html, Output, Input, State, ctx, MATCH, ALL, dcc
from dash_extensions.enrich import DashProxy, OperatorTransform, OperatorOutput, Operator, MultiplexerTransform
app = DashProxy( __name__, transforms=[OperatorTransform(), MultiplexerTransform()], suppress_callback_exceptions=True)
def new_view2(index):
return html.Div(f"Triggered 0", id={"type": "second-txt", "index": index}, style={"height": "23px"})
def new_view(index):
return html.Button(f"Button {index}", id={"type": "action-btn", "index": index}, n_clicks=0, style={"height": "23px"})
@app.callback(
Output({"type": "second-txt", "index": MATCH}, "children"),
Input({"type": "action-btn", "index": MATCH}, "n_clicks"),
Input({"type": "second-txt", "index": MATCH}, "children"),
prevent_initial_call=True
)
def inc_counter_for_view(clicks, triggered):
return f"Triggered {int(triggered.split()[1]) + 1}"
app.layout = html.Div([
html.Button("Add View", id="add-view"),
dcc.Store("items-store", data=[], storage_type="memory"),
html.Div([
html.Div([], id="v1", style={"display": "flex", "flex-direction": "column", "gap": "5px"}),
html.Div([], id="v2", style={"display": "flex", "flex-direction": "column", "gap": "5px"}),
],
style={"display": "flex", "flex-direction": "row", "gap": "5px", "margin-top": "5px"}
)]
)
app.clientside_callback(
"""
function(data, v1, v2) {
v1.push(data.v1)
v2.push(data.v2)
return [v1, v2]
}
""",
Output("v1", "children"),
Output("v2","children"),
Input("items-store", "data"),
State("v1","children"),
State("v2","children"),
prevent_initial_call=True
)
@app.callback(
Output("items-store", "data"),
Input("add-view", "n_clicks"),
State({"type": "action-card", "index": ALL}, "id"),
prevent_initial_call=True,
)
def add_view(index, views):
return {
"v1": new_view(index),
"v2": new_view2(index)
}
app.run_server(debug=False)