How to clear the value in dropdown via callback

Hi! I design two dropdown, “region_choose” and “country_choose”. I hope when I select options in the “region_choose” dropdown, the value in the “country_choose” should be cleared. When I select options in “country_choose”, the value in the “region_choose” should be cleared. I try to use callback to connect the two dropdowns. However, it shows Error loading dependencies. And I don’t know how to fix it.

region drop down

dcc.Dropdown(
id = ‘region_choose’,
options = [
{‘label’: ‘all’, ‘value’:‘all’},
{‘label’: ‘South East Asia’, ‘value’:‘South East Asia’},
{‘label’: ‘AUS&NZL’, ‘value’:‘AUS&NZL’},
{‘label’: ‘CHX&HKG’, ‘value’:‘CHX&HKG’}
],
placeholder = “Select a region”,
value = ‘all’,
style=dict(
width = ‘800px’
)
),

country drop down

html.Label(‘country’),
dcc.Dropdown(
id = ‘country_choose’,
options = [
{‘label’: i, ‘value’:i} for i in list1
],
placeholder = “Select a country”,
value = ‘CHN’,
style=dict(
width = ‘800px’
)
),

@app.callback(
Output(‘country_choose’,‘value’),
[Input(‘region_choose’,‘value’)])
def link_dropdown(region_value):
if region_value != None:
return None

@app.callback(
Output(‘region_choose’,‘value’),
[Input(‘country_choose’,‘value’)])
def link_dropdown2(country_value):
if country_value != None:
return None

So, your error was due to not having return values in both callbacks when the if condition was not satisfied. Also, you would have run into another problem as your callbacks would have an infinite loop. Not sure if you intended this to be the case, but based on your dropdowns, I would think you would want hte country dropdown to be populated based on what region was selected.

The following code, slightly tweaking yours (and since you didn’t include a self-supporting example), works.

I removed one of your callbacks and combined them into one. If the user selects the region dropdown, you can return a new dropdown for the country based on this selection.

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

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server
app.config.suppress_callback_exceptions = True
app.css.config.serve_locally = False

list1 = ['Country1', 'Country2', 'Country3']

app.layout = html.Div(
    children=[
        html.Div(
            children=[
                dcc.Dropdown(
                    id='region_choose',
                    options=[
                        {'label': 'all', 'value': 'all'},
                        {'label': 'South East Asia', 'value': 'South East Asia'},
                        {'label': 'AUS & NZL', 'value': 'AUS & NZL'},
                        {'label': 'CHX & HKG', 'value': 'CHX & HKG'}
                    ],
                    placeholder='Select a region',
                    style=dict(
                        width='800px'
                    )
                ),
            ],
            id='region_dropdown'
        ),

        html.Div(
            children=[
                dcc.Dropdown(
                    id='country_choose',
                    options=[
                        {'label': i, 'value': i} for i in list1
                    ],
                    placeholder='Select a country',
                    style=dict(
                        width='800px'
                    )
                ),
            ],
            id='country_dropdown'
        )
    ]
)


def clicked(ctx):
    if not ctx.triggered or not ctx.triggered[0]['value']:
        return None
    else:
        return ctx.triggered[0]['prop_id'].split('.')[0]


@app.callback(
    output=[Output('country_dropdown', 'children'),
            Output('region_dropdown', 'children')],
    inputs=[Input('region_choose', 'value'),
            Input('country_choose', 'value')])
def link_dropdown(region_value, country_value):
    # Define dropdowns
    country_dropdown = dcc.Dropdown(
        id='country_choose',
        options=[
            {'label': i, 'value': i} for i in list1
        ],
        placeholder='Select a country',
        style=dict(
            width='800px'
        )
    )

    region_dropdown = dcc.Dropdown(
        id='region_choose',
        options=[
            {'label': 'all', 'value': 'all'},
            {'label': 'South East Asia', 'value': 'South East Asia'},
            {'label': 'AUS & NZL', 'value': 'AUS & NZL'},
            {'label': 'CHX & HKG', 'value': 'CHX & HKG'}
        ],
        placeholder='Select a region',
        style=dict(
            width='800px'
        )
    )

    user_clicked = clicked(dash.callback_context)
    print(u'''clicked = {}'''.format(user_clicked))
    if user_clicked == 'region_choose' and region_value:
        # return a country dropdown with countries based on region selected
        return country_dropdown, no_update
    elif user_clicked == 'country_choose' and country_value:
        # do no update either dropdowns (you can if you want, but for getting this work I didn't want to update them)
        return no_update, no_update
    else:
        # Ensure return values are populated if other conditions aren't met
        return no_update, no_update


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

Hi flyingcujo, thanks for your help. What I hope to do is that to clear the value of the dropdown. For example, when the user clicks the region dropdown, I hope the value in the country dropdpwn is cleared automatically. When the user clicks the country dropdown, keep the region dropdown having no value. But in the process, I hope to clear the value not the options. I couldn’t find a way to jump out of the infinite loop.

In other words, I force the user only use one of the two dropdown at the same time.

kind of. In my app where drops downs or other componets are dependent on others being populated first, I disable them and then within the callbacks I check if the preconditions to enable them have been met.

The problem I noticed in your initial post was your statemen that when the user selects options in “country_choose”, the value in “region_choose” should be cleared. But since “region_choose” is an input to a callback that sets “country_choose”, you are entering the infinite loop. no update return values can help with this but I think what you really want is to set some sort of precidence order with respect to your dropdowns. I did this via enabling/disabling the components.