Skip to content

Commit

Permalink
Merge pull request #2867 from plotly/fix/clientside_no_output
Browse files Browse the repository at this point in the history
Fix clientside no outputs
  • Loading branch information
T4rk1n committed May 27, 2024
2 parents 993b57f + 0cce4c0 commit 4a9f09a
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- [#2854](https://github.com/plotly/dash/pull/2854) Fix dcc.Dropdown resetting empty values to null and triggering callbacks. Fixes [#2850](https://github.com/plotly/dash/issues/2850)
- [#2859](https://github.com/plotly/dash/pull/2859) Fix base patch operators. fixes [#2855](https://github.com/plotly/dash/issues/2855)
- [#2856](https://github.com/plotly/dash/pull/2856) Fix multiple consecutive calls with same id to set_props only keeping the last props. Fixes [#2852](https://github.com/plotly/dash/issues/2852)
- [#2867](https://github.com/plotly/dash/pull/2867) Fix clientside no output callback. Fixes [#2866](https://github.com/plotly/dash/issues/2866)

## [2.17.0] - 2024-05-03

Expand Down
2 changes: 2 additions & 0 deletions dash/_callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ def register_clientside_callback(
**kwargs,
):
output, inputs, state, prevent_initial_call = handle_callback_args(args, kwargs)
no_output = isinstance(output, (list,)) and len(output) == 0
insert_callback(
callback_list,
callback_map,
Expand All @@ -559,6 +560,7 @@ def register_clientside_callback(
state,
None,
prevent_initial_call,
no_output=no_output,
)

# If JS source is explicitly given, create a namespace and function
Expand Down
20 changes: 11 additions & 9 deletions dash/dash-renderer/src/actions/callbacks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,16 +278,18 @@ async function handleClientside(
returnValue = await returnValue;
}

zipIfArray(outputs, returnValue).forEach(([outi, reti]) => {
zipIfArray(outi, reti).forEach(([outij, retij]) => {
const {id, property} = outij;
const idStr = stringifyId(id);
const dataForId = (result[idStr] = result[idStr] || {});
if (retij !== dc.no_update) {
dataForId[cleanOutputProp(property)] = retij;
}
if (outputs) {
zipIfArray(outputs, returnValue).forEach(([outi, reti]) => {
zipIfArray(outi, reti).forEach(([outij, retij]) => {
const {id, property} = outij;
const idStr = stringifyId(id);
const dataForId = (result[idStr] = result[idStr] || {});
if (retij !== dc.no_update) {
dataForId[cleanOutputProp(property)] = retij;
}
});
});
});
}
} catch (e) {
if (e === dc.PreventUpdate) {
status = STATUS.PREVENT_UPDATE;
Expand Down
46 changes: 45 additions & 1 deletion tests/integration/callbacks/test_arbitrary_callbacks.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import time
from multiprocessing import Value

from dash import Dash, Input, Output, html, set_props, register_page
from dash import (
Dash,
Input,
Output,
html,
set_props,
register_page,
clientside_callback,
)


def test_arb001_global_set_props(dash_duo):
Expand Down Expand Up @@ -188,3 +196,39 @@ def on_click(_):
dash_duo.wait_for_style_to_equal(
"#output", "background-color", "rgba(255, 0, 0, 1)"
)


def test_arb007_clientside_no_output(dash_duo):
app = Dash()

app.layout = [
html.Button("start", id="start1"),
html.Button("start2", id="start2"),
html.Div(id="output"),
]

clientside_callback(
"""
function(_) {
dash_clientside.set_props('output', {children: 'start1'})
}
""",
Input("start1", "n_clicks"),
prevent_initial_call=True,
)
clientside_callback(
"""
function(_) {
dash_clientside.set_props('output', {children: 'start2'})
}
""",
Input("start2", "n_clicks"),
prevent_initial_call=True,
)

dash_duo.start_server(app)

dash_duo.find_element("#start1").click()
dash_duo.wait_for_text_to_equal("#output", "start1")
dash_duo.find_element("#start2").click()
dash_duo.wait_for_text_to_equal("#output", "start2")

0 comments on commit 4a9f09a

Please sign in to comment.