Dash app client-side callback not passing value to server-side callback

I'm working on a Dash app integrated with a Django template, and I'm encountering an issue where a client-side callback is not passing a value to a server-side callback. The value is correctly logged in the browser's console but appears as None on the server side when the server-side callback is triggered.

**Minimal Code **

# template.html
{% load plotly_dash %}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script>
            setTimeout(function() {
                function getSelectedLAName() {
                    const selected_la_name_element = document.getElementById('selected-la-name');
                    if (selected_la_name_element) {
                        const selected_la_name = selected_la_name_element.getAttribute('data-la-name');
                        console.log("Selected LA Name:", selected_la_name);
                        return selected_la_name;
                    } else {
                        console.log("Element not found");
                        return null;
                    }
                }

                getSelectedLAName();  // Call the function to test
            }, 500);  // Delay in milliseconds
        </script>
    </head>
    <body>
        <h1>DASH APP Test</h1>
        <div id="selected-la-name" data-la-name="{{ selected_la.search_term }}"></div>
        {{ selected_la.search_term }} 
        <div id="dash-container" style="width: 100%; height: 600px; border: 1px solid red;">
             {% plotly_app name="dash_app" ratio=1 %}
        </div>
    </body>
</html>
# dash_app.py
from django_plotly_dash import DjangoDash
from dash import dcc, html
from dash.dependencies import Input, Output
from common.common_utils import *
import plotly.graph_objects as go

app = DjangoDash('dash_app')

app.layout = html.Div([
    html.Div(id='selected_la_name', style={'display': 'none'}),
    dcc.Dropdown(
        id='data-type',
        options=[
            {'label': 'Number', 'value': 'number'},
            {'label': 'Percentage', 'value': 'percentage'}
        ],
        value='number',
        style={'height': '30px', 'width': '50%', 'font-size': '16px'}
    ),
    dcc.Graph(
        id='heatmap',
        style={'height': '600px', 'padding': '8px'}
    )
])

# Client-side callback to extract value from hidden div
app.clientside_callback(
    """
    function() {
        const selected_la_name_element = document.getElementById('selected-la-name');
        return selected_la_name_element ? selected_la_name_element.getAttribute('data-la-name') : null;
    }
    """,
    Output('selected_la_name', 'children'),
    Input('heatmap', 'id')  # Dummy input to trigger the callback
)

# Server-side callback to update the graph
@app.callback(
    Output('heatmap', 'figure'),
    [Input('data-type', 'value'),
     Input('selected_la_name', 'children')]
)
def update_graph(data_type, selected_la_name):
    print(f"Received selected_la_name: {selected_la_name}") 
    if not selected_la_name:
        return go.Figure()  

    if data_type == 'number':
        data_norm, data = func_name(selected_la_name)
    else:
        data_norm, data = func_name(selected_la_name)

    fig = go.Figure(data=go.Heatmap(
        x=data_norm.columns,
        y=data_norm.index,
        z=data_norm.values
    ))
    return fig

OUTPUTS

In template.html

  • console.log("Selected LA Name:", selected_la_name);
    Output is correct

  • {{ selected_la.search_term }}
    output is correct

in dash_app.py

  • print(f"Received selected_la_name: {selected_la_name}")
    Outputs: None (ie incorrect)

What I Have Tried:

  • Verified that the data-la-name attribute is correctly set in the HTML.
  • Checked that the client-side callback is executed and logs the expected value.
  • Ensured there is a delay to allow the DOM to fully load, but the issue persists.

Additional Information:

  • Dash version 2.9.3
  • Django version 4.2.13
  • django-plotly-dash version 2.3.1

Thank you for your help!

Back to Top