"TypeError: Cannot read properties of undefined" using clientside_callback in dash python

What is happening to me is probably very similar to this Clientside Callback Cannot read properties of undefined - #10 by nikok.

I am using dash and manitine components to create a website. To keep control over packages and running the website I am using poetry. The website should have a clientside_callback for when clicking a button (with any kind of action like alert or console.log() to see that it works). I wanted to use ClientsideFunction to register the callback.

When implementing the callback using ClientsideFunction and running the website with poetry run -m website I get the error

TypeError: Cannot read properties of undefined (reading 'showAlert')
    at _callee2$ (callbacks.ts:160:40)
    at tryCatch (callbacks.ts:2:1)
    at Generator.<anonymous> (callbacks.ts:2:1)
    at Generator.next (callbacks.ts:2:1)
    at asyncGeneratorStep (callbacks.ts:2:1)
    at _next (callbacks.ts:2:1)
    at callbacks.ts:2:1
    at new Promise (<anonymous>)
    at callbacks.ts:2:1
    at _handleClientside (callbacks.ts:209:2)

showAlert is defined like this in /assets/js/callbacks.js.

window.dash_clientside = Object.assign({}, window.dash_clientside, {
    clientside: {
        showAlert: function(n_clicks) {
            console.log("this worked!");
            return '';
        }
    }
});

In callbacks.py I have defined namespace and function_name that should be present in a js file (which is /assets/js/callbacks.js).

from dash import dash, Output, State, Input, callback_context, clientside_callback, ClientsideFunction

def get_callbacks(app):
    app.clientside_callback(
        ClientsideFunction(
            namespace="clientside",  # Namespace in the JavaScript file
            function_name="showAlert"  # Function name defined in the JavaScript file
        ),
        Output('connection_status', 'color'),
        Input('vnc_connect', 'n_clicks')
    )

This is __main__.py where the server gets the layout and callbacks.

import dash_mantine_components as dmc
from dash import Dash, _dash_renderer, html, Input, Output, callback, State
from website.layout import get_layout
from website.callbacks import get_callbacks

_dash_renderer._set_react_version("18.2.0")

app = Dash(assets_ignore=r"(?!callbacks\.js).*") # I only want this file to run

app.layout = get_layout()

get_callbacks(app)

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True, port="8000")

This is layout.py with three simple components from mantine.

import dash_mantine_components as dmc
from dash import html

def get_layout():
    return dmc.MantineProvider(
        [
            dmc.Container([
                dmc.Badge("Disconnected", variant="dot", color="yellow", id="connection_status"),
                dmc.Button("Connect to Server", id="vnc_connect", w=200),
                dmc.PasswordInput(label="Server Password", w=200, id="server_password",placeholder="Server password", required=True),
            ])
        ]
    )

This is my current directory structure

├── poetry.lock
├── pyproject.toml
└── website
    ├── __init__.py
    ├── __main__.py
    ├── assets
    │   └── js
    │       └── callbacks.js
    ├── callbacks.py
    └── layout.py

The error is not always 100% persistent when reloading the page, but persistent enough to cause trouble on the client side.

My problem seems to be a bit similar to this problem. When imbeding javascript in the callback directly like this it works much better.

def get_callbacks(app):
    app.clientside_callback(
        """
        function(value) {
            alert("asd");
        }
        """,
        Output('connection_status', 'color'),
        Input('vnc_connect', 'n_clicks')
    )

But why he gets undefined when trying to put the javascriot in a js file instead is not answered.

After digging a bit I saw that when putting the javascript in a file and it does work it is seen here, and when it doesnt work its not seen.

Why would my required js file sometimes appear, and other times not? And how do I fix it?

For now I have began to include callbacks.js (and other js files) by using embedded javascript to put a script tag at the bottom of the html body. It works consistently if i do that.

Hello @LittleCake
Do you have the same problem if you run your app without Poetry? i.e. directly python app.py

Maybe you could try to inspect resources loaded by your browser when you load the page. And see if yhe callbacks.js is properly loaded (Developer tools > Network).
I would try to see if there is a pattern

  • is the problem here when you restart the app ? (may it be because of hot reloading ?)
  • is the problem here when you reload the page without cache (CTRL+R usually works)