Quantcast
Channel: 🎛️ Dash - Plotly Community Forum
Viewing all articles
Browse latest Browse all 6271

Circular Dependency Problem; Disabling/enabling Button

$
0
0

Dear Dash Community,

I have a problem with a circular dependency in a multi-page Dash app. Usually, I ignore those warnings as the callbacks still fire, but this time it’s different. See below a simplified version:

import dash
import time
import dash_bootstrap_components as dbc
import dash_html_components as html
from dash.dependencies import Input, Output
from dash import callback_context, no_update

app = dash.Dash(__name__,  external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = dbc.Card(
        [
            html.Div(id="start-trigger"),
            html.Div(id="finished-trigger"),
            dbc.Button(
                dbc.Row(
                    [
                        dbc.Spinner(id="button-spinner", size="sm",
                                    spinner_style={"display": "none"}),
                        "Start Calculation"
                    ],
                    no_gutters=True
                ),
                id="start-button",
                color="success",
                size="md",
                n_clicks=0
            ),
        ]
    )


@app.callback(
    [Output("start-button", "disabled"),
     Output("button-spinner", "spinner_style"),
     Output("start-trigger", "children")],
    [Input("start-button", "n_clicks"),
     Input("finished-trigger", "children")],
    prevent_initial_call=True)
def helper_calculation(_, __):
    if callback_context.triggered[0]["prop_id"] == "start-button.n_clicks":
        return True, {"margin": ".3rem .65rem 0 0"}, "start-trigger"
    else:
        return False, {"display": "none"}, no_update


@app.callback(
    Output("finished-trigger", "children"),
    [Input("start-trigger", "children")],
    prevent_initial_call=True)
def long_calculation(_):
    time.sleep(5)
    return "calculation finished"


if __name__ == "__main__":
    app.run_server(debug=True)

The code is supposed to do the following:

  1. Upon button press, the button shall be deactivated to prevent further callbacks of the same calculation, the progress-spinner shall be shown, and the start-trigger (invisible Div) shall be updated

  2. Upon a change of the start-trigger, the long calculation shall be started and once it’s finished, the finished-trigger shall be updated

  3. Upon a change of the finished-trigger, the button shall be activated again and the progress-spinner shall become invisible again. Notice the “no_update” in the else tree of the first callback to prevent the same calculation from happening again.

Currently, step 1 and 2 work. But although the finished trigger is updated, the first callback is not triggered and hence the spinner keeps spinning and the button stays deactivated

Any idea how I can make this work?

1 post - 1 participant

Read full topic


Viewing all articles
Browse latest Browse all 6271

Latest Images

Trending Articles



Latest Images