Clientside Callback Cannot read properties of undefined

I want to use a clientside callback to create a bbox for a tooltip programmatically. This will hopefully allow me to add the tooltip to a graph at a corresponding vertex when I click on a dash table.

My question is why does a test clientside callback that returns null to a dummy variable throws the error

Cannot read properties of undefined (reading ‘data’)

(This error originated from the built-in JavaScript code that runs Dash apps. Click to see the full stack trace or open your browser’s console.)
TypeError: Cannot read properties of undefined (reading ‘data’)

at _callee2$ (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_7_0m1670590103.dev.js:573:58)

at tryCatch (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_7_0m1670590103.dev.js:409:2404)

at Generator._invoke (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_7_0m1670590103.dev.js:409:1964)

at Generator.next (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_7_0m1670590103.dev.js:409:3255)

at asyncGeneratorStep (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_7_0m1670590103.dev.js:413:103)

at _next (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_7_0m1670590103.dev.js:414:194)

at http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_7_0m1670590103.dev.js:414:364

at new Promise (<anonymous>)

at http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_7_0m1670590103.dev.js:414:97

at handleClientside (http://127.0.0.1:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_7_0m1670590103.dev.js:525:28)

Sample code is below.

from jupyter_dash import JupyterDash
from dash import Dash, dcc, html, no_update, dash_table, callback_context, State, Input, Output
from dash.exceptions import PreventUpdate
import plotly.express as px
import pandas as pd

dict_list = [{‘fid’:1, ‘field1’:‘test1’, ‘x’:1, ‘y’:1}, {‘fid’:2, ‘field1’:‘test2’, ‘x’:2, ‘y’:2}, {‘fid’:3, ‘field1’:‘test3’, ‘x’:3, ‘y’:1}]
df = pd.DataFrame(dict_list)
fig = px.line(df, x=‘x’, y=‘y’, hover_data=[df.fid])
fig.update_traces(
hoverinfo=“none”,
hovertemplate=None,
marker=dict(size=30)
)

app = JupyterDash(name)

app.layout = html.Div(className=“container”,
children=[dcc.Store(id=“get_tooltip”), dcc.Store(id=“get_tooltip2”),dash_table.DataTable(id=‘flight_table’, data = dict_list,
columns=[{“name”: i, “id”: i} for i in [‘fid’, ‘field1’]],
page_current=0,
page_size=20,
page_action=‘custom’,
filter_action=‘custom’,
filter_query=‘’,
sort_action=‘custom’,
sort_mode=‘multi’,
sort_by=,
style_filter_conditional=[{
‘if’: {‘column_id’: ‘date_processed’},
‘pointer-events’: ‘None’}]),

    dcc.Graph(
        id="asp_graph",
        figure=fig,
        clear_on_unhover=True),
    dcc.Tooltip(
        id="graph-tooltip",
        background_color="lightgrey",
        border_color="blue"),
],

)

@app.callback(
Output(“get_tooltip”, “data”),
Output(“flight_table”, “active_cell”),
Input(“asp_graph”, “clickData”),
Input(“asp_graph”, “figure”),
Input(“flight_table”, “active_cell”),
Input(“flight_table”, “data”),
State(“flight_table”, “page_size”)
)
def main_func(clickData, dict_fig, active_cell, flight_table, page_size):
triggered_id = callback_context.triggered[0][‘prop_id’]

if 'asp_graph.clickData' == triggered_id:
    fid = clickData['points'][0]['customdata'][0]
    try:
        idx = df.index[df['fid'] == fid][0]
        activecell, selectedcells = [None, []]
    except:
        idx = 0
        activecell, selectedcells = [None, []]
    return fid, active_cell
elif 'flight_table.active_cell' == triggered_id:
    fid = flight_table[active_cell['row']]['fid']
    return fid, active_cell
else:
    raise PreventUpdate

app.clientside_callback(
“”"
function(fid) {
return null
}
“”",
Output(“get_tooltip2”, “data”),
Input(“get_tooltip”, “data”),
)

Hi @jgm ,

could you please format your code so that we can copy&paste it?

Where do you use this variables?

Hello @jgm,

I think this may be because on initial load, your dcc store doesn’t have anything.

Try giving it an empty list.

I haven’t implemented a use for ActitveCell and selectedCellss yet in this test script. In my working code I use Active cell to add a hyperlink to the table and to get data to link to a graph and map.

Giving it an empty list didn’t work. The code above mysteriously started working, then after making changes, it stopped.

What version of dash are you running?

Hi there,

I don’t know what this app actually does, but the callback structure works as far as I can tell. I don’t get any error message. Maybe I am missing something. Try this:

from dash import Dash, dcc, html, dash_table, callback_context, State, Input, Output
from dash.exceptions import PreventUpdate
import plotly.express as px
import pandas as pd

dict_list = [
    {
        'fid': 1,
        'field1': 'test1',
        'x': 1,
        'y': 1
    },
    {
        'fid': 2,
        'field1': 'test2'
        , 'x': 2,
        'y': 2
    },
    {
        'fid': 3,
        'field1': 'test3',
        'x': 3,
        'y': 1
    }
]
df = pd.DataFrame(dict_list)
fig = px.scatter(df, x='x', y='y', hover_data=[df.fid])
fig.update_traces(
    hoverinfo="none",
    hovertemplate=None,
    marker=dict(size=30)
)

app = Dash(__name__)

app.layout = html.Div(
    className="container",
    children=[
        dcc.Store(id="get_tooltip"),
        dcc.Store(id="get_tooltip2"),
        dash_table.DataTable(
            id='flight_table',
            data=dict_list,
            columns=[{"name": i, "id": i} for i in ['fid', 'field1']],
            page_current=0,
            page_size=20,
            page_action='custom',
            filter_action='custom',
            filter_query='',
            sort_action='custom',
            sort_mode='multi',
            # sort_by=,
            style_filter_conditional=[
                {
                    'if': {'column_id': 'date_processed'},
                    'pointer-events': 'None'
                }
            ]
        ),

        dcc.Graph(
            id="asp_graph",
            figure=fig,
            clear_on_unhover=True
        ),
        dcc.Tooltip(
            id="graph-tooltip",
            background_color="lightgrey",
            border_color="blue"
        ),
        html.Div(id='dummy'),
        html.Div(id='dummy2')
    ],

)


@app.callback(
    Output("dummy2", "children"),
    Output("get_tooltip", "data"),
    # Output("flight_table", "active_cell"),
    Input("asp_graph", "clickData"),
    Input("asp_graph", "figure"),
    Input("flight_table", "active_cell"),
    Input("flight_table", "data"),
    State("flight_table", "page_size")
)
def main_func(clickData, dict_fig, active_cell, flight_table, page_size):
    triggered_id = callback_context.triggered[0]['prop_id']

    if 'asp_graph.clickData' == triggered_id:
        fid = clickData['points'][0]['customdata'][0]
        try:
            idx = df.index[df['fid'] == fid][0]
            activecell, selectedcells = [None, []]
        except:
            idx = 0
            activecell, selectedcells = [None, []]
        return fid, active_cell
    elif 'flight_table.active_cell' == triggered_id:
        fid = flight_table[active_cell['row']]['fid']
        return fid, active_cell
    else:
        raise PreventUpdate


app.clientside_callback(
    """
    function(fid) {
        return ['output from clientside callback: random number', Math.random()]
    }
    """,
    Output("dummy", "children"),
    # Output("get_tooltip2", "data"),
    Input("get_tooltip", "data"),
    prevent_initial_call=True
)

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

It works for me if I put the clientside callback in the assets folder as a .js.

I’m using jupyter-dash 0.4.2 and dash 2.7.0

That error happens frequently when using debug mode for me.