Skip to content
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from multiprocessing import Lock
from dash import Dash, Input, Output, dcc, html
from dash import Dash, Input, Output, dcc, html, MATCH, ALL
from dash.dependencies import stringify_id
from dash.testing import wait
import time
Expand Down Expand Up @@ -417,7 +417,7 @@ def updateDiv(n_clicks):

# update multiple props of same component, only targeted id/prop triggers spinner
# test that target_components id can be a dict id
def test_ldcp011_loading_component_target_components(dash_dcc):
def test_ldcp010_loading_component_target_components(dash_dcc):
lock = Lock()

app = Dash(__name__)
Expand Down Expand Up @@ -461,7 +461,7 @@ def updateDiv2(n_clicks):

dash_dcc.start_server(app)

btn1id = "#" + stringify_id({"type": "button", "index": "one"})
btn1id = "[id='" + stringify_id({"type": "button", "index": "one"}) + "']"

dash_dcc.wait_for_text_to_equal(btn1id, "content 1")

Expand Down Expand Up @@ -839,3 +839,50 @@ def update_btn1_children(n_clicks):
assert spinners == []

assert dash_dcc.get_logs() == []


# loading spinner triggers when callback Output uses ALL wildcard
def test_ldcp019_loading_component_pattern_matching(dash_dcc):
lock = Lock()

app = Dash(__name__)

app.layout = html.Div(
[
dcc.Loading(
[
html.Div(
id={"type": "div-1", "index": 1, "name": "test"},
className="div-1",
)
],
className="loading",
)
],
id={"type": "root", "index": 1, "name": "test"},
className="root",
)

@app.callback(
Output({"type": "div-1", "index": ALL, "name": MATCH}, "children"),
Input({"type": "root", "index": ALL, "name": MATCH}, "n_clicks"),
)
def updateDiv(n_clicks):
if n_clicks == [1]:
time.sleep(0.1)
return ["changed"]
return ["content"]

with lock:
dash_dcc.start_server(app)
dash_dcc.wait_for_text_to_equal(".div-1", "content")

dash_dcc.find_element(".root").click()

dash_dcc.find_element(".loading .dash-spinner")
# mounted but hidden, so looks like no text
dash_dcc.wait_for_text_to_equal(".div-1", "")

dash_dcc.wait_for_text_to_equal(".div-1", "changed")

assert dash_dcc.get_logs() == []
2 changes: 1 addition & 1 deletion dash/dash-renderer/src/actions/callbacks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ export function executeCallback(
}

const __execute = async (): Promise<CallbackResult> => {
const loadingOutputs = outputs.map(out => ({
const loadingOutputs = flatten(outputs).map(out => ({
path: getPath(paths, out.id),
property: out.property?.split('@')[0],
id: stringifyId(out.id)
Expand Down
Loading