5 Dropdown Callback

I have 5 dropdowns that are on a chained callback (I think). Here is my set-up:

@app.callback(
    Output('drop-2', 'options'),
    Input('drop-1', 'value'),
    State('points-table', 'data'),
    prevent_initial_call=True
)
def update_drop_2(value, data):
    df = pd.DataFrame.from_dict(data)
    return np.sort(df[df.Area_0 == value].Area_1.unique())


@app.callback(
    Output('drop-3', 'options'),
    State('drop-1', 'value'),
    Input('drop-2', 'value'),
    State('points-table', 'data'),
    prevent_initial_call=True
)
def update_drop_3(value1, value2, data):
    df = pd.DataFrame.from_dict(data)
    df_1 = df[df['Area_0'] == value1]
    return np.sort(df_1[df_1.Area_1 == value2].Area_2.unique())


@app.callback(
    Output('drop-4', 'options'),
    State('drop-1', 'value'),
    State('drop-2', 'value'),
    Input('drop-3', 'value'),
    State('points-table', 'data'),
    prevent_initial_call=True
)
def update_drop_4(value1, value2, value3, data):
    df = pd.DataFrame.from_dict(data)
    df_1 = df[df['Area_0'] == value1]
    df_2 = df_1[df_1['Area_1'] == value2]
    return np.sort(df_2[df_2.Area_2 == value3].Area_3.unique())


@app.callback(
    Output('drop-5', 'options'),
    State('drop-1', 'value'),
    State('drop-2', 'value'),
    State('drop-3', 'value'),
    Input('drop-4', 'value'),
    State('points-table', 'data'),
    prevent_initial_call=True
)
def update_drop_5(value1, value2, value3, value4, data):
    df = pd.DataFrame.from_dict(data)
    df_1 = df[df['Area_0'] == value1]
    df_2 = df_1[df_1['Area_1'] == value2]
    df_3 = df_2[df_2['Area_2'] == value3]
    return np.sort(df_3[df_3.Area_3 == value4].Area_4.unique())

My first dropdown comes from a static list of inputs. The rest continue to filter and narrow down based off the previous input. However it’s running slow. When debugging I found that for instance it’s trying to run ‘update_drop_4’ when I’ve only changed drop-1. I thought with how I have State and Input that it shouldn’t be going until drop-3 is triggered. Any thoughts?

You need to have a catch if there isn’t a value selected.

Since you are technically adjusting the 2nd option, this triggers the 3rd, etc.

So I started to try this:

@app.callback(
    Output('drop-2', 'options'),
    Input('drop-1', 'value'),
    State('points-table', 'data'),
    prevent_initial_call=True
)
def update_drop_2(value, data):
    if value:
        df = pd.DataFrame.from_dict(data=data)
        return np.sort(df[df.Area_0 == value].Area_1.unique())
    else:
        return dash.no_update

And it will populate my second drop down, but now I can’t select an option?

I get this error: Cannot read properties of null (reading ‘length’)

With what you have given, I cant really test your code out.

Can you please provide a working example to use?

I think I got it with this:

@app.callback(
    Output('drop-2', 'options'),
    Input('drop-1', 'value'),
    State('points-table', 'data'),
    prevent_initial_call=True
)
def update_drop_2(value, data):
    if not value:
        raise dash.exceptions.PreventUpdate
    else:
        df = pd.DataFrame.from_dict(data=data)
        return np.sort(df[df.Area_0 == value].Area_1.unique())


@app.callback(
    Output('drop-3', 'options'),
    State('drop-1', 'value'),
    Input('drop-2', 'value'),
    State('points-table', 'data'),
    prevent_initial_call=True
)
def update_drop_3(value1, value2, data):
    if not value2:
        raise dash.exceptions.PreventUpdate
    else:
        df = pd.DataFrame.from_dict(data)
        df_1 = df[df['Area_0'] == value1]
        return np.sort(df_1[df_1.Area_1 == value2].Area_2.unique())


@app.callback(
    Output('drop-4', 'options'),
    State('drop-1', 'value'),
    State('drop-2', 'value'),
    Input('drop-3', 'value'),
    State('points-table', 'data'),
    prevent_initial_call=True
)
def update_drop_4(value1, value2, value3, data):
    if not value3:
        raise dash.exceptions.PreventUpdate
    else:
        df = pd.DataFrame.from_dict(data)
        df_1 = df[df['Area_0'] == value1]
        df_2 = df_1[df_1['Area_1'] == value2]
        return np.sort(df_2[df_2.Area_2 == value3].Area_3.unique())


@app.callback(
    Output('drop-5', 'options'),
    State('drop-1', 'value'),
    State('drop-2', 'value'),
    State('drop-3', 'value'),
    Input('drop-4', 'value'),
    State('points-table', 'data'),
    prevent_initial_call=True
)
def update_drop_5(value1, value2, value3, value4, data):
    if not value4:
        raise dash.exceptions.PreventUpdate
    else:
        df = pd.DataFrame.from_dict(data)
        df_1 = df[df['Area_0'] == value1]
        df_2 = df_1[df_1['Area_1'] == value2]
        df_3 = df_2[df_2['Area_2'] == value3]
        return np.sort(df_3[df_3.Area_3 == value4].Area_4.unique())

Am I using dash.exceptions.PreventUpdate properly?

1 Like