Skip to content

[BUG] Long callback function executed without being triggered #1985

@keurfonluu

Description

@keurfonluu

Describe your context
Please provide us your environment, so we can easily reproduce the issue.

dash                      2.3.0
dash-bootstrap-components 1.0.3
dash-core-components      2.0.0
dash-html-components      2.0.0
dash-table                5.0.0
dash-vtk                  0.0.9

Describe the bug

I have a rather complex app where the layout content is generated by a callback (single page app). For one specific layout content, I need a long callback because one callback function takes some time to execute. The problem is that, somehow, right after the layout is generated, the long callback is triggered automatically (even when using prevent_initial_call). No problem if I use a standard callback, though.

Please find below a sample script to reproduce this issue based on the long callback example in the documentation. I also defined a validation_layout as recommended by the documentation.

import dash
from dash import html
from dash.long_callback import DiskcacheLongCallbackManager
from dash.dependencies import Input, Output

import diskcache
cache = diskcache.Cache("./cache")
long_callback_manager = DiskcacheLongCallbackManager(cache)

app = dash.Dash(
    __name__,
    suppress_callback_exceptions=True,
    long_callback_manager=long_callback_manager,
)

layout1 = html.Div(
    [
        html.Button("Generate layout", id="button_1"),
        html.Div(id="main"),
    ],
)
layout2 = html.Div(
    [
        html.Div([html.P(id="paragraph_id", children=["Button not clicked"])]),
        html.Button(id="button_id", children="Run Job!"),
    ]
)

app.layout = layout1
app.validation_layout = html.Div([layout1, layout2])

@app.callback(
    Output("main", "children"),
    Input("button_1", "n_clicks"),
    prevent_initial_call=True,
)
def generate_layout(n_clicks):
    return layout2

@app.long_callback(
    Output("paragraph_id", "children"),
    Input("button_id", "n_clicks"),
    prevent_initial_call=True,
)
def callback(n_clicks):
    return [f"Clicked {n_clicks} times"]

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

Execute the app, click on "Generate layout", wait a few seconds, "paragraph_id" children will automatically change to "Clicked None times".

Expected behavior

The long callback not to be triggered after the new layout is generated. For the example above, the children property of the component "paragraph_id" to be updated only when the button is clicked.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions