Dash DataTable stays empty when layout is injected via Tabs callback (callbacks not firing / data not set)

I’m building a Dash app with dcc.Tabs. The tab content is rendered via a “router” callback that returns a layout object. Inside that layout I have a dash_table.DataTable that should be filled by a callback, but the table renders with headers only and never gets data.

The DataTable appears (columns render), but data is always empty. No errors shown in the browser UI. The debug console shows no callback errors.

So my code simplifyed is somthing like this:

#main.py
import pandas as pd
from dash import Dash, dash_table, html, dcc, Input, Output
import dash_bootstrap_components as dbc
from clicks_productos_layout import clicks_productos_layout


# Crear la app Dash
# --------------------------------
app = Dash(__name__)
app.config.suppress_callback_exceptions = True
server = app.server

app.layout = dbc.Container(
    [
        html.H1("Clicks", className="my-4"),
        dcc.Tabs(
            id="tabs_principales",
            value="tab_clicks",
            children=[
                dcc.Tab(label="Clicks Generales", value="tab_clicks"),
                dcc.Tab(label="Otro Análisis", value="tab_otro_analisis"),
            ],
        ),
        html.Div(id="contenido_tabs", className="mt-4"),
    ],
    fluid=True,
)

@app.callback(Output("contenido_tabs", "children"), 
              Input("tabs_principales", "value"))

def actualizar_contenido(tab):
    if tab == "tab_clicks":
        return clicks_productos_layout
    return html.Div("En construcción...")

import clicks_productos_callbacks 

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





#I have a clicks_productos_callback.py which I fully simplified for this example.
#clicks_productos_callback.py
from dash import Input, Output, State
from main import app
from clicks_productos_layout import clicks_productos_layout
from tablas_base import tabla_clicks
import pandas as pd

@app.callback(
    Output("tabla_clicks_general", "data"),
)

def cargar_tabla(_n):
    tabla_clicks_general = tabla_clicks.head()
    return tabla_clicks_general.to_dict("records")


# And I have a Layout that I also simplified for this example.
#clicks_productos_layout.py
from dash import html, dash_table, dcc
import dash_bootstrap_components as dbc
import pandas as pd

clicks_productos_layout = html.Div([
    dbc.Container([
         dash_table.DataTable(
            id="tabla_clicks_general",
            columns=[
                {"name": "carro", "id": "carro"},
                {"name": "clicks", "id": "clicks"},
                {"name": "conv", "id": "conv"},
                {"name": "departamento", "id": "departamento"},
                {"name": "dia", "id": "dia"},
                {"name": "fecha", "id": "fecha"},
                {"name": "linea", "id": "linea"},
                {"name": "marca", "id": "marca"},
                {"name": "origen", "id": "origen"},
                {"name": "precio", "id": "precio"},
                {"name": "producto", "id": "producto"},
                {"name": "semana", "id": "semana"},
                {"name": "sku_corto", "id": "sku_corto"},
                {"name": "sku_largo", "id": "sku_largo"},
                {"name": "sku_mod", "id": "sku_mod"},
                {"name": "sub_linea", "id": "sub_linea"},
                {"name": "trim", "id": "trim"},
                {"name": "unidades_vendidas", "id": "unidades_vendidas"},
                {"name": "venta", "id": "venta"},
            ],
            page_size=10,
            style_table={'overflowX': 'auto'},
            style_cell={'textAlign': 'center', 'fontSize': '13px', 'padding': '5px'},
            style_header={'fontWeight': 'bold', 'backgroundColor': '#f8f9fa'},
            style_data_conditional=[
                {'if': {'row_index': 'odd'}, 'backgroundColor': '#f9f9f9'},
                {'if': {'filter_query': '{departamento} = "total general"'},
                'fontWeight': 'bold', 'backgroundColor': '#e9ecef'},
            ],
        ),

        html.Br(),
    ], style={"maxWidth": "1200px", "margin": "0 auto"})
])

I’m building a Dash app with dcc.Tabs. The tab content is rendered via a “router” callback that returns a layout object. Inside that layout I have a dash_table.DataTable that should be filled by a callback, but the table renders with headers only and never gets data.

The DataTable appears (columns render), but data is always empty. No errors shown in the browser UI. The debug console shows no callback errors.

So my code simplifyed is somthing like this:

python

# I have a main that goes like this:

python

#main.py
import pandas as pd
from dash import Dash, dash_table, html, dcc, Input, Output
import dash_bootstrap_components as dbc
from clicks_productos_layout import clicks_productos_layout


# Crear la app Dash
# --------------------------------
app = Dash(__name__)
app.config.suppress_callback_exceptions = True
server = app.server

app.layout = dbc.Container(
    [
        html.H1("Clicks", className="my-4"),
        dcc.Tabs(
            id="tabs_principales",
            value="tab_clicks",
            children=[
                dcc.Tab(label="Clicks Generales", value="tab_clicks"),
                dcc.Tab(label="Otro Análisis", value="tab_otro_analisis"),
            ],
        ),
        html.Div(id="contenido_tabs", className="mt-4"),
    ],
    fluid=True,
)

@app.callback(Output("contenido_tabs", "children"), 
              Input("tabs_principales", "value"))

def actualizar_contenido(tab):
    if tab == "tab_clicks":
        return clicks_productos_layout
    return html.Div("En construcción...")

import clicks_productos_callbacks 

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





#I have a clicks_productos_callback.py which I fully simplified for this example.
#clicks_productos_callback.py
from dash import Input, Output, State
from main import app
from clicks_productos_layout import clicks_productos_layout
from tablas_base import tabla_clicks
import pandas as pd

@app.callback(
    Output("tabla_clicks_general", "data"),
)

def cargar_tabla(_n):
    tabla_clicks_general = tabla_clicks.head()
    return tabla_clicks_general.to_dict("records")


# And I have a Layout that I also simplified for this example.
#clicks_productos_layout.py
from dash import html, dash_table, dcc
import dash_bootstrap_components as dbc
import pandas as pd

clicks_productos_layout = html.Div([
    dbc.Container([
         dash_table.DataTable(
            id="tabla_clicks_general",
            columns=[
                {"name": "carro", "id": "carro"},
                {"name": "clicks", "id": "clicks"},
                {"name": "conv", "id": "conv"},
                {"name": "departamento", "id": "departamento"},
                {"name": "dia", "id": "dia"},
                {"name": "fecha", "id": "fecha"},
                {"name": "linea", "id": "linea"},
                {"name": "marca", "id": "marca"},
                {"name": "origen", "id": "origen"},
                {"name": "precio", "id": "precio"},
                {"name": "producto", "id": "producto"},
                {"name": "semana", "id": "semana"},
                {"name": "sku_corto", "id": "sku_corto"},
                {"name": "sku_largo", "id": "sku_largo"},
                {"name": "sku_mod", "id": "sku_mod"},
                {"name": "sub_linea", "id": "sub_linea"},
                {"name": "trim", "id": "trim"},
                {"name": "unidades_vendidas", "id": "unidades_vendidas"},
                {"name": "venta", "id": "venta"},
            ],
            page_size=10,
            style_table={'overflowX': 'auto'},
            style_cell={'textAlign': 'center', 'fontSize': '13px', 'padding': '5px'},
            style_header={'fontWeight': 'bold', 'backgroundColor': '#f8f9fa'},
            style_data_conditional=[
                {'if': {'row_index': 'odd'}, 'backgroundColor': '#f9f9f9'},
                {'if': {'filter_query': '{departamento} = "total general"'},
                'fontWeight': 'bold', 'backgroundColor': '#e9ecef'},
            ],
        ),

        html.Br(),
    ], style={"maxWidth": "1200px", "margin": "0 auto"})
])

I’ve tried every thing and just cant mannage to display the data on my table.

Can any body please help me?

hi there,

I haven’t worked with DDT for a while, but my guess is that the issue you’re seeing is related to those data-related attributes, yes, there’s more than one, and they affect different stages of the rendering process, especially while you’re trying to make it working with Tabs.

My suggestion is: why not try the brand-new community component Dash DAG? It’s fresh, open-source alternative with a cleaner architecture, more active contributors, and much better reference materials.

thx

Hi @frank123

It would be easier to help if you can make a complete minimal example that replicates the issue.
Do you see the same issue if the table is not in a tab?