Skip to content

[BUG] Callback running keyword doesn't work when component is not in layout #2897

@aGitForEveryone

Description

@aGitForEveryone

When using the running keyword in a regular callback, the renderer throws an error if the component defined in running does not exist. In my case that happened, because I am targeting a button that is not always part of the layout. The callback that is triggered by clicking the button can also be triggered by a silent background process when the button is not in the layout.

The error that is thrown is:

TypeError: Cannot read properties of undefined (reading 'concat')

    at getInputHistoryState (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_17_1m1718952684.dev.js:9446:78)

    at http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_17_1m1718952684.dev.js:9475:26

    at http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_17_1m1718952684.dev.js:9519:12

    at dispatch (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_17_1m1718952684.dev.js:44147:22)

    at http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_17_1m1718952684.dev.js:43826:16

    at dispatch (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_17_1m1718952684.dev.js:44550:28)

    at http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_17_1m1718952684.dev.js:689:5

    at http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_17_1m1718952684.dev.js:43822:18

    at dispatch (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_17_1m1718952684.dev.js:44550:28)

    at http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_17_1m1718952684.dev.js:744:7

Here is a small example to reproduce the bug. Click the button for the error to appear. Note the component id used in running, it refers to a non existing component:

from dash import Dash, html, Input, Output, callback, set_props
import time

app = Dash(__name__)


app.layout = html.Div(
    [
        html.H1("Updating Component While Callback is Running"),
        html.Div(
            "Data saved and downloaded successfully!",
            id="alert",
            style={"display": "none"},
        ),
        html.Button("Save as CSV", id="save-as-csv"),
    ]
)


@callback(
    Input("save-as-csv", "n_clicks"),
    running=[(Output("non_existing_component", "disabled"), True, False)],
)
def update_output_div(_):
    print("Saving data...")
    time.sleep(3)
    set_props("alert", {"style": {"display": "block"}})


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

A solution for the bug is to add a check to see if the componentPath that was fetched is "undefined" in the function updateComponent.

function updateComponent(component_id, props) {
  return function (dispatch, getState) {
    var paths = getState().paths;
    var componentPath = (0,_paths__WEBPACK_IMPORTED_MODULE_7__.getPath)(paths, component_id);
    if (typeof component_id === 'undefined') {
      // Can't find the component that was defined in the running keyword,
      // Let's skip the component to prevent the dashboard from crashing.
      return;
    }
    ... rest of code ...

The entry point for this function is handleServerside (with if (running) == True -> sideUpdate -> updateComponent
As far as I understood the code, updateComponent is the first point in this flow where it is actually checked whether the component exists.

In the proposed solution the component update is simply skipped if the path is undefined.

I will create a PR to propose this solution. One question I have here is whether the updateComponent function is the proper place to add the check.

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