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:
Using Dash version 2.9.3
Using Django version 4.2.13
Thank you for your help!