Black Lives Matter. Please consider donating to Black Girls Code today.

Updating based on a third cascaded dropdown

Hi,

I am trying to display some graphs based on three nested dropdown menu’s.

At first I had only two nested dropdown menu’s and this worked fine. Selecting an option from the first dropdown populates the options of the second dropdown and selects a default value. The setting of a value in the second dropdown then triggers my graphs, based on the Input[] from dropdown_2 and the State[] of dropdown_1. Again this worked fine.

However now I want to add a third dropdown, whose options and default value get set dependent on the values of the first two dropdowns. Then I want to trigger a display based on the values of all three options. This then triggers a dependency error.

Here is some code that reproduces the error:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, Event

app = dash.Dash()

app.layout = html.Div([
    dcc.Dropdown(id='dropdown_a', options = [{'label': 'A', 'value': 'A'}, {'label': 'B', 'value': 'B'}]),
    dcc.Dropdown(id='dropdown_b'),
    dcc.Dropdown(id='dropdown_c'),
    html.Div(id='output_area')
])

@app.callback(
    Output('dropdown_b', 'options'),
    [Input('dropdown_a', 'value')])
def set_dropdown_b_options(value):
    if value=='A': options_b = [{'label': 'C', 'value': 'C'}, {'label': 'D', 'value': 'D'}]
    if value == 'B': options_b = [{'label': 'E', 'value': 'E'}, {'label': 'F', 'value': 'F'}]
    return options_b

@app.callback(
    Output('dropdown_b', 'value'),
    [Input('dropdown_a', 'value')])
def set_dropdown_b_value(value):
    if value=='A': value_b = 'C'
    if value == 'B': value_b = 'E'
    return value_b

@app.callback(
    Output('dropdown_c', 'options'),
    [Input('dropdown_b', 'value')])
def set_dropdown_b_options(value):
    if value=='C': options_c = [{'label': '1', 'value': '1'}, {'label': '2', 'value': '2'}]
    if value == 'D': options_c = [{'label': '3', 'value': '3'}, {'label': '4', 'value': '4'}]
    if value=='E': options_c = [{'label': '5', 'value': '5'}, {'label': '6', 'value': '6'}]
    if value == 'F': options_c = [{'label': '7', 'value': '7'}, {'label': '8', 'value': '8'}]
    return options_c

@app.callback(
    Output('dropdown_c', 'value'),
    [Input('dropdown_b', 'value')])
def set_dropdown_b_options(value):
    if value=='C': value_c = '1'
    if value == 'D': value_c = '3'
    if value=='E': value_c = '5'
    if value == 'F': value_c = '7'
    return value_c

@app.callback(
    Output('output_area', 'children'),
    [Input('dropdown_c', 'value')],
    [State('dropdown_b', 'value')],
    [State('dropdown_a', 'value')])
def print_test(value_c, value_b, value_a):
    return "a:" + value_a + " b: " + value_b + " c: " + value_c

# @app.callback(
#     Output('output_area', 'children'),
#     [Input('dropdown_c', 'value')])
# def print_test(value_c): #, value_b, value_a):
#     return "c: " + value_c

if __name__ == '__main__':

    app.run_server(debug=True)

The code that is commented out works fine as it only depends on the value of dropdown_c. However the callback that depends on all thee inputs, i.e. [Input('dropdown_c', 'value')], [State('dropdown_b', 'value')], [State('dropdown_a', 'value')]), generates the following error:

Traceback (most recent call last):
File “/Users/oegedijk/Documents/Projects/ab-dash/dropdown_cascade_test.py”, line 55, in
[State(‘dropdown_a’, ‘value’)])
File “/Users/oegedijk/anaconda3/lib/python3.6/site-packages/dash/dash.py”, line 491, in callback
self._validate_callback(output, inputs, state, events)
File “/Users/oegedijk/anaconda3/lib/python3.6/site-packages/dash/dash.py”, line 374, in _validate_callback
name.lower(), str(arg), name
dash.exceptions.IncorrectTypeException: The event argument <dash.dependencies.State object at 0x10da57668> is not of type dash.Event.

Any ideas how to make this work?

Nevermind, I found the error: had to put the square brackets around both State variables:

@app.callback(
    Output('output_area', 'children'),
    [Input('dropdown_c', 'value')],
    [State('dropdown_b', 'value'),
    State('dropdown_a', 'value')])
def print_test(value_c, value_b, value_a):
    return "a:" + value_a + " b: " + value_b + " c: " + value_c

Still new to this stuff :slight_smile:

1 Like