Skip to content

[BUG] Multi-output leads to callback results being ignored #1084

Closed
@slishak

Description

@slishak

Describe your context

dash                    1.7.0
dash-core-components    1.6.0
dash-html-components    1.0.2
dash-renderer           1.2.2
dash-table              4.5.1

Describe the bug

When using multi-outputs in the following code snippet (set MULTI = True), the labels are not reliably updated when clicking the button to update the slider values.

To reproduce:

  • Start the app
  • Click the button to set both slider values to 5
  • Change both slider values manually to a different number. Both labels update correctly
  • Click the button again. Only the second label is updated, not the first, despite both update_slider1_label and update_slider2_label being called
import dash

import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate

APP = dash.Dash(__name__)
APP.layout = html.Div([
    html.Div([
        html.Button('Button', id='button'),
    ]),
    html.Div([
        html.Label(id='label1'),
        dcc.Slider(id='slider1', min=0, max=10, value=0),

    ]),
    html.Div([
        html.Label(id='label2'),
        dcc.Slider(id='slider2', min=0, max=10, value=0),
    ])
])


MULTI = True

if MULTI:
    @APP.callback(
        [Output('slider1', 'value'),
         Output('slider2', 'value')],
        [Input('button', 'n_clicks_timestamp')]
    )
    def update_slider_vals(n_clicks_timestamp):
        if not n_clicks_timestamp:
            raise PreventUpdate
        return 5, 5
else:
    @APP.callback(
        Output('slider1', 'value'),
        [Input('button', 'n_clicks_timestamp')]
    )
    def update_slider1_val(n_clicks_timestamp):
        if not n_clicks_timestamp:
            raise PreventUpdate
        return 5

    @APP.callback(
        Output('slider2', 'value'),
        [Input('button', 'n_clicks_timestamp')]
    )
    def update_slider2_val(n_clicks_timestamp):
        if not n_clicks_timestamp:
            raise PreventUpdate
        return 5


@APP.callback(
    Output('label1', 'children'),
    [Input('slider1', 'value')]
)
def update_slider1_label(val):
    ret = f'Slider1 value {val}'
    print(ret)
    return ret


@APP.callback(
    Output('label2', 'children'),
    [Input('slider2', 'value')]
)
def update_slider2_label(val):
    ret = f'Slider2 value {val}'
    print(ret)
    return ret


if __name__ == '__main__':
    APP.run_server(port=6060)

Expected behavior

In this example, both labels should always be updated to reflect the slider value, regardless of whether there is one callback doing both or each label has its own callback.

Screenshots

image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions