Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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

Closed
aGitForEveryone opened this issue Jun 21, 2024 · 0 comments · Fixed by #2898
Closed

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

aGitForEveryone opened this issue Jun 21, 2024 · 0 comments · Fixed by #2898

Comments

@aGitForEveryone
Copy link
Contributor

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.

@aGitForEveryone aGitForEveryone changed the title Callback running keyword doesn't work when component is not in layout [BUG] Callback running keyword doesn't work when component is not in layout Jun 21, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant