-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix multiple concurrent loading states #1310
Conversation
forEach(p => { | ||
target = (target[p] = | ||
target[p] ?? | ||
p === 'children' ? [] : {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out ??
has higher precedence than ?
in JS 🙈 The only necessary part of this fix is the extra parentheses around this line.
Added the typeof path[i + 1]
clause so that the []
vs {}
distinction is correct - though it doesn't seem to actually cause problems when the container has the wrong type 🤷
Do we want to test loading states for chained callbacks too? Dropdown A ➡️ Dropdown B ➡️ Graph. If Dropdown A changes, do we show a loading state for Graph before Dropdown B is updated? I'm not sure what the existing behavior is but seems like it could be another piece of logic that could've changed during the refactor. |
Sure, I can add a test for that later tonight. |
Here is a test case for chained callbacks & loading states: import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import time
app = dash.Dash(__name__)
app.layout = html.Div([
html.Button(id='button', children='Start', n_clicks=0),
html.Div(
dcc.Loading(html.Div(id='output-1', style={
'width': 200,
'height': 200,
'backgroundColor': 'hotpink',
})),
style={'display': 'inline-block'}
),
html.Div(
dcc.Loading(html.Div(id='output-2', style={
'width': 200,
'height': 200,
'backgroundColor': 'rebeccapurple',
})),
style={'display': 'inline-block'}
),
html.Div(
dcc.Loading(html.Div(id='output-3', style={
'width': 200,
'height': 200,
'backgroundColor': 'green',
})),
style={'display': 'inline-block'}
),
html.Div(
dcc.Loading(html.Div(id='output-4', style={
'width': 200,
'height': 200,
'backgroundColor': '#FF851B', # orange
})),
style={'display': 'inline-block'}
)
])
@app.callback(Output('output-1', 'children'), [Input('button', 'n_clicks')])
def update_output_2(n_clicks):
time.sleep(2)
return 'Output 1: {}'.format(n_clicks)
@app.callback(Output('output-2', 'children'), [Input('output-1', 'children')])
def update_output_2(children):
time.sleep(2)
return 'Output 2: {}'.format(children)
@app.callback([Output('output-3', 'children'), Output('output-4', 'children')], [Input('output-2', 'children')])
def update_output_2(children):
time.sleep(2)
return [
'Output 3: {}'.format(children),
'Output 4: {}'.format(children)
]
if __name__ == '__main__':
app.run_server(debug=True) In 1.12.0 we don't display a loading state for grandchildren, only immediate children. Looks like the 1.13 behavior is the same right now. Here's what this looks like in 1.12.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💃 beautiful
This release upgrades dash-renderer from v1.4.1 to v1.5.1, and is timed with the release of Dash for Python v1.13.4. This update also addresses a regression that prevented multiple loading states from displaying concurrently when a callback updates multiple outputs, as noted in [plotly/dash#1310](plotly/dash#1310).
Fixes https://github.com/plotly/dash-core/issues/195
Regression from #1254 - only one loading state could be shown at a time.
I have run the tests locally and they passed. (refer to testing section in contributing)
I have added tests, or extended existing tests, to cover any new features or bugs fixed in this PR
I have added entry in the
CHANGELOG.md