Chained callbacks in tabs cause error msg. 'Div' object has no attribute 'keys'

Hi everyone,

I am trying to build a dashboard with three tabs. Within each tab I would like to display data from different sources.

With the following sample code, I get the error message ‘Div’ object has no attribute ‘keys’ which I cannot interprete properly. I read through other topics of this forum but cannot find a soultion to my problem.

Can anyone help by chance? That would be great :slightly_smiling_face:

UPDATE: I posted the correct code. First draft was buggy.

Code:

import dash
import pandas as pd
import plotly.graph_objs as go
import dash_html_components as html
import dash_core_components as dcc

from dash.dependencies import Input, Output

app = dash.Dash(__name__)

# generate data
import numpy as np
df = pd.DataFrame(np.random.randint(0,100,size=(100, 7)), columns=list('ABCDEFG'))
# get feature names
available_indicators = df.columns.values


# App layout
app.layout = html.Div([
    dcc.Tabs(id="tabs", value='tab_b', children=[
        dcc.Tab(label='Tab A', value='tab_a'),
        dcc.Tab(label='Tab B', value='tab_b'),
        dcc.Tab(label='Tab C', value='tab_c')
    ]),
    html.Div(id='tabs-content')
])

@app.callback(Output('tabs-content', 'children'),
              [Input('tabs', 'value')])
def render_content(tab):
    if tab == 'tab_a':
        return html.Div([
            html.H3('Tab A content')
        ])
        
    elif tab == 'tab_b':
        return html.Div(children=[
                        dcc.Dropdown(id='feature',
                            options=[{'label': i, 'value': i} for i in available_indicators],
                            value=[''],
                            multi=False 
                        ),
                        
                        dcc.Graph(id='example-graph'),
                    ])  
    elif tab == 'tab_c':
        return html.Div([
            html.H3('Tab C content')
        ])

@app.callback(Output('example-graph', 'figure'),
              [Input('feature', 'value')])
def update_plots(feature):
    dff = df[feature]
    return dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': df.index, 'y': ddf.values, 'type': 'line', 'name': input_data},
            ],
            'layout': {
                'title': input_data
            }
        }
    )

if __name__ == '__main__':
    app.run_server(debug=0)

Good news. I have found a nice soultion here.

Code:

import dash
import pandas as pd
import plotly.graph_objs as go
import dash_html_components as html
import dash_core_components as dcc

from dash.dependencies import Input, Output

app = dash.Dash(__name__)

# generate data
import numpy as np
df = pd.DataFrame(np.random.randint(0,100,size=(100, 7)), columns=list('ABCDEFG'))
# get feature names
available_indicators = df.columns.values

# Tab layout
tab1_layout = [
    html.Div([
        html.H2("TBD. 2 FFTs")
    ])
]

tab2_layout = [
    html.Div(children=[
        dcc.Dropdown(id='feature',
            options=[{'label': i, 'value': i} for i in available_indicators],
            value=['C'],
            multi=False 
        ),
        html.Div(id='tab2_content'),
    ])
]

tab3_layout = [
    html.Div([
        html.H2("TBD.")
    ])
]

# App layout
app.layout = html.Div([
    dcc.Tabs(id="tabs", value='tab_b', children=[
        dcc.Tab(label='Tab A', value='tab_a', children=tab1_layout),
        dcc.Tab(label='Tab B', value='tab_b', children=tab2_layout),
        dcc.Tab(label='Tab C', value='tab_c', children=tab3_layout)
    ]),
])

@app.callback(
    Output('tab2_content', 'children'),
    [Input('feature', 'value')])
def update_plots(feature):
    ddf = df[feature]
    return dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': df.index, 'y': ddf.values, 'type': 'line', 'name': feature},
            ],
            'layout': {
                'title': feature
            }
        }
    )

if __name__ == '__main__':
    app.run_server(debug=1)