Skip to content

Commit 62806f3

Browse files
authoredMay 1, 2020
Merge pull request #1224 from plotly/1223-initialcall
fix #1223 - initialcall on new layout chunk edge case
2 parents 5b2ced7 + 3234e4b commit 62806f3

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed
 

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
88
- [#1078](https://github.com/plotly/dash/pull/1078) Permit usage of arbitrary file extensions for assets within component libraries
99

1010
### Fixed
11+
- [#1224](https://github.com/plotly/dash/pull/1224) Fixes [#1223](https://github.com/plotly/dash/issues/1223), a very specific situation in which initial callbacks will not fire.
1112
- [#1220](https://github.com/plotly/dash/pull/1220) Fixes [#1216](https://github.com/plotly/dash/issues/1216), a set of related issues about pattern-matching callbacks with `ALL` wildcards in their `Output` which would fail if no components matched the pattern.
1213
- [#1212](https://github.com/plotly/dash/pull/1212) Fixes [#1200](https://github.com/plotly/dash/issues/1200) - prior to Dash 1.11, if none of the inputs to a callback were on the page, it was not an error. This was, and is now again, treated as though the callback raised PreventUpdate. The one exception to this is with pattern-matching callbacks, when every Input uses a multi-value wildcard (ALL or ALLSMALLER), and every Output is on the page. In that case the callback fires as usual.
1314
- [#1201](https://github.com/plotly/dash/pull/1201) Fixes [#1193](https://github.com/plotly/dash/issues/1193) - prior to Dash 1.11, you could use `flask.has_request_context() == False` inside an `app.layout` function to provide a special layout containing all IDs for validation purposes in a multi-page app. Dash 1.11 broke this when we moved most of this validation into the renderer. This change makes it work again.

‎dash-renderer/src/actions/dependencies.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -1214,10 +1214,14 @@ export function getCallbacksInLayout(graphs, paths, layoutChunk, opts) {
12141214
if (callback) {
12151215
const foundIndex = foundCbIds[callback.resolvedId];
12161216
if (foundIndex !== undefined) {
1217-
callbacks[foundIndex].changedPropIds = mergeMax(
1218-
callbacks[foundIndex].changedPropIds,
1217+
const foundCb = callbacks[foundIndex];
1218+
foundCb.changedPropIds = mergeMax(
1219+
foundCb.changedPropIds,
12191220
callback.changedPropIds
12201221
);
1222+
if (callback.initialCall) {
1223+
foundCb.initialCall = true;
1224+
}
12211225
} else {
12221226
foundCbIds[callback.resolvedId] = callbacks.length;
12231227
callbacks.push(callback);

‎tests/integration/callbacks/test_multiple_callbacks.py

+40
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,43 @@ def on_click(n_clicks):
262262
dash_duo.wait_for_text_to_equal("#output", "1")
263263
dash_duo.find_element("#btn").click()
264264
dash_duo.wait_for_text_to_equal("#output", "2")
265+
266+
267+
def test_cbmt007_early_preventupdate_inputs_above_below(dash_duo):
268+
app = dash.Dash(__name__, suppress_callback_exceptions=True)
269+
app.layout = html.Div(id="content")
270+
271+
@app.callback(Output("content", "children"), [Input("content", "style")])
272+
def content(_):
273+
return html.Div([
274+
html.Div(42, id="above-in"),
275+
html.Div(id="above-dummy"),
276+
html.Hr(),
277+
html.Div(0, id='above-out'),
278+
html.Div(0, id='below-out'),
279+
html.Hr(),
280+
html.Div(id="below-dummy"),
281+
html.Div(44, id="below-in"),
282+
])
283+
284+
# Create 4 callbacks - 2 above, 2 below.
285+
for pos in ('above', 'below'):
286+
@app.callback(
287+
Output("{}-dummy".format(pos), "children"),
288+
[Input("{}-dummy".format(pos), "style")]
289+
)
290+
def dummy(_):
291+
raise PreventUpdate
292+
293+
@app.callback(
294+
Output('{}-out'.format(pos), 'children'),
295+
[Input('{}-in'.format(pos), 'children')]
296+
)
297+
def out(v):
298+
return v
299+
300+
dash_duo.start_server(app)
301+
302+
# as of https://github.com/plotly/dash/issues/1223, above-out would be 0
303+
dash_duo.wait_for_text_to_equal("#above-out", "42")
304+
dash_duo.wait_for_text_to_equal("#below-out", "44")

0 commit comments

Comments
 (0)
Please sign in to comment.