Murcielago
Murcielago

Reputation: 1005

plotly dash: callback to update data-table silently failing

I have a data-table displayed on screen and I built a litle dropdown menu because I want to filter the table based on the value selected on this widget. While no error gets outputed, the table does not update. It just remains the same. I have followed this post for help Plotly Dash table callback. I feel like I am super close but cannot figure out what is wrong.

here is what I have been able to do so far: html code:

app.layout = html.Div(children=[
    
        html.Br(),
        html.Br(),
        html.Br(),
    
        #,style={'border':'solid 0.1em','border-color': 'transparent transparent #ff5402','font-size':'1em', 'color':'#ff5402'}),
        
    html.Div(children=[
        html.Div(
            html.Div(html.H1("Demand planning"),
                    
                     className="col-sm-12 inline-block")),
        html.Br(),
        
        
        
    html.Br(),
    html.Div(children=[
      
      html.Div([
        dcc.Dropdown(
                id='item',
                options=[{'label': name, 'value': name} for name in available_items],
                value='choose an item')
      
      ]),
        
 
        html.Br(),
                
             
                
 html.Div(children=[
  
        html.Br(),
                
        html.Div(children=[
            html.Div(html.H4("Forecast"),style={'padding-left':10}),
    
            dash_table.DataTable(
            id='table',
            columns=[{"name": i, "id": i} for i in forecast.columns],
            style_cell={'whiteSpace': 'normal','height': 'auto',},
            data=forecast.to_dict('rows'),
            sort_action='native',
            filter_action='none',
            export_format='csv',
            
            page_action = 'native',
            page_current = 0,
            page_size = 10,
            style_cell_conditional = [
                               
                                {'if': {'column_id': 'Id'},
                                  'width': '30%', 'textAlign':'left'},
                                       {'if': {'column_id': 'QuantityMin'},
                                  'width': '30%', 'textAlign':'left'},
                                       {'if': {'column_id': 'QuantityMax'},
                                  'width': '30%', 'textAlign':'left'},
                                         {'if': {'column_id': 'Probability'},
                                  'width': '30%', 'textAlign':'left'},
                                    
                             ],
           style_data_conditional=[
                {'backgroundColor': 'rgba(0, 0, 0,0)'}],
            style_header={'backgroundColor': 'rgb(230, 230, 230)','font-size' : '10px'})
       
        ],  
                 
                 
 className= "mx-auto justify-content-left", style={'display': 'inline-block', "width":800,"height":475,"margin": 5}),##ca va avec le children du datatable
 
             
    ],className="row justify-content-center",style={'display': 'flex','align': 'center','heigh':475,'textAlign': 'center','border':'solid 0.05em','border-color': 'lightgray'}
              ), #celui la cest celui au dessus du Br()
                
          
                
                
    ],className='container', style={'padding-top':10, 'padding-bottom':50}), #ca c;est le children entre les deux br
            
            
    ])
    
])

and callback

@app.callback(
    Output('table-container', 'children'),
    [Input('item', 'name')],)

def update_figure(forecast):
    print('name')
    forecast = forecast[forecast['Id'] == 'name']
    print(forecast)
    
    

    return html.Div(
        [
            dash_table.DataTable(id='table', columns=[{'id': name, 'value': name} for name in forecast.columns.values])
        ]
    )
    

here is the error output in the log:

    forecast = forecast[forecast['Id'] == 'name']
TypeError: 'NoneType' object is not subscriptable


I would be grateful if someone could help me find out why the table is not updating?

Upvotes: 1

Views: 2512

Answers (1)

bas
bas

Reputation: 15722

I'm guessing you don't see the errors, because you have suppress_callback_exceptions set to True.

The problem with your callback is that is that your output looks like this:

Output('table', 'figure')

table is a DataTable and has no property figure.

What you could do instead is surround the table by a div, let's call this table-container and change the output in the callback to this:

Output("table-container", "children")

Adjusted layout:

app.layout = html.Div(
    children=[
        html.Br(),
        html.Br(),
        html.Br(),
        # ,style={'border':'solid 0.1em','border-color': 'transparent transparent #ff5402','font-size':'1em', 'color':'#ff5402'}),
        html.Div(
            children=[
                html.Div(
                    html.Div(
                        html.H1("Demand planning"), className="col-sm-12 inline-block"
                    )
                ),
                html.Br(),
                html.Br(),
                html.Div(
                    children=[
                        html.Div(
                            [
                                dcc.Dropdown(
                                    id="item",
                                    options=[
                                        {"label": name, "value": name}
                                        for name in available_items
                                    ],
                                    value="choose an item",
                                )
                            ]
                        ),
                        html.Br(),
                        html.Div(
                            children=[
                                html.Br(),
                                html.Div(
                                    children=[
                                        html.Div(
                                            html.H4("Forecast"),
                                            style={"padding-left": 10},
                                        ),
                                        html.Div(
                                            id="table-container",
                                            children=[
                                                dash_table.DataTable(
                                                    id="table",
                                                    columns=[
                                                        {"name": i, "id": i}
                                                        for i in forecast.columns
                                                    ],
                                                    style_cell={
                                                        "whiteSpace": "normal",
                                                        "height": "auto",
                                                    },
                                                    data=forecast.to_dict("rows"),
                                                    sort_action="native",
                                                    filter_action="none",
                                                    export_format="csv",
                                                    page_action="native",
                                                    page_current=0,
                                                    page_size=10,
                                                    style_cell_conditional=[
                                                        {
                                                            "if": {"column_id": "Id"},
                                                            "width": "30%",
                                                            "textAlign": "left",
                                                        },
                                                        {
                                                            "if": {
                                                                "column_id": "QuantityMin"
                                                            },
                                                            "width": "30%",
                                                            "textAlign": "left",
                                                        },
                                                        {
                                                            "if": {
                                                                "column_id": "QuantityMax"
                                                            },
                                                            "width": "30%",
                                                            "textAlign": "left",
                                                        },
                                                        {
                                                            "if": {
                                                                "column_id": "Probability"
                                                            },
                                                            "width": "30%",
                                                            "textAlign": "left",
                                                        },
                                                    ],
                                                    style_data_conditional=[
                                                        {
                                                            "backgroundColor": "rgba(0, 0, 0,0)"
                                                        }
                                                    ],
                                                    style_header={
                                                        "backgroundColor": "rgb(230, 230, 230)",
                                                        "font-size": "10px",
                                                    },
                                                ),
                                            ],
                                        ),
                                    ],
                                    className="mx-auto justify-content-left",
                                    style={
                                        "display": "inline-block",
                                        "width": 800,
                                        "height": 475,
                                        "margin": 5,
                                    },
                                ),  ##ca va avec le children du datatable
                            ],
                            className="row justify-content-center",
                            style={
                                "display": "flex",
                                "align": "center",
                                "heigh": 475,
                                "textAlign": "center",
                                "border": "solid 0.05em",
                                "border-color": "lightgray",
                            },
                        ),  # celui la cest celui au dessus du Br()
                    ],
                    className="container",
                    style={"padding-top": 10, "padding-bottom": 50},
                ),  # ca c;est le children entre les deux br
            ]
        ),
    ]
)

Also 'value' is not a valid key for columns, I think you're looking for 'name' instead.

For a minimal example, see the documentation here.


An general example of how a callback that filters the DataTable data based on the input value could look like:

@app.callback(
    Output("table-container", "children"),
    [Input("item", "value")],
)
def update_figure(input_value):
    dff = forecast[forecast["species"] == input_value]

    return html.Div(
        [
            dash_table.DataTable(
                id="table",
                columns=[{"id": name, "name": name} for name in dff.columns.values],
                data=dff.to_dict("records"),
            )
        ]
    )

In the example above I've set forecast equal to the iris data set and changed the filter slightly, because I don't know what your data looks like.

Upvotes: 1

Related Questions