How to insert several dropdowns in plotly dash

All,

I am trying to get into using Plotly Dash and I am getting stuck on this one piece where I would like to dynamically add a user-defined number of dropdowns. Here is what I tried:

# Import required libraries
import dash
import math
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State


# App Begins
app = dash.Dash(
    __name__, meta_tags=[{"name": "viewport", "content": "width=device-width"}],
)
app.title = "Tool"
server = app.server

# Create global chart template
mapbox_access_token = "pk.eyJ1IjoicGxvdGx5bWFwYm94IiwiYSI6ImNrOWJqb2F4djBnMjEzbG50amg0dnJieG4ifQ.Zme1-Uzoi75IaFbieBDl3A"

layout = dict(
    autosize=True,
    automargin=True,
    margin=dict(l=30, r=30, b=20, t=40),
    hovermode="closest",
    plot_bgcolor="#F9F9F9",
    paper_bgcolor="#F9F9F9",
    legend=dict(font=dict(size=10), orientation="h"),
    title="Satellite Overview",
    mapbox=dict(
        accesstoken=mapbox_access_token,
        style="light",
        center=dict(lon=-78.05, lat=42.54),
        zoom=7,
    ),
)

# Create app layout
app.layout = html.Div(
    [
        dcc.Store(id="aggregate_data"),
        # empty Div to trigger javascript file for graph resizing
        html.Div(id="output-clientside"),
        html.Div(
            [
                html.Div(
                    [
                        html.Img(
                            src=app.get_asset_url("dash-logo.png"),
                            id="plotly-image",
                            style={
                                "height": "60px",
                                "width": "auto",
                                "margin-bottom": "25px",
                            },
                        )
                    ],
                    className="one-third column",
                ),
                html.Div(
                    [
                        html.Div(
                            [
                                html.H3(
                                    "Dash Tool",
                                    style={"margin-bottom": "0px"},
                                ),
                            ]
                        )
                    ],
                    className="one-half column",
                    id="title",
                ),
            ],
            id="header",
            className="row flex-display",
            style={"margin-bottom": "25px"},
        ),
        html.Div(
            [
                html.Div(
                    [
                        html.P("Quantity 1:", className="control_label"),
                        dcc.Input(
                           id="quantity_1",
                           type="number",
                           placeholder=33.
                        ),
                        html.P("Quantity 2:", className="control_label"),
                        dcc.Input(
                            id="quantity_2",
                            type="number",
                            placeholder=-115.
                        ),
                        html.P("Number of Drop Downs:", className="control_label"),
                        dcc.Slider(
                            id="drop_downs",
                            min=2,
                            max=10,
                            value=2,
                            step=1.0,
                            className="dcc_control",
                        ),
                        html.P("Load Inputs:", className="control_label"),
                        dcc.Checklist(
                            id='sources_flag',
                            options=[
                                {'label': 'Yes', 'value': 'Y'},
                            ],
                            value=['Y'],
                            labelStyle={'display': 'inline-block'}
                        ),
                        html.Div(id='source_dropdown_container', children=[]),
                        html.Div(id='source_dropdown_container_output'),
                        html.Div(id='source_file_container', children=[]),
                        html.Div(id='source_file_container_output'),
                    ],
                    className="pretty_container four columns",
                    id="cross-filter-options",
                ),
            ],
            className="row flex-display",
        ),
    ],
    id="mainContainer",
    style={"display": "flex", "flex-direction": "column"},
)


# Create callbacks
@app.callback(
    [
        Output(component_id='source_dropdown_container_output', component_property='children'),
    ],
    [
        Input(component_id='drop_downs', component_property='value'),
        Input(component_id='sources_flag', component_property='value'),
    ]
)
def update_source_dropdowns(value, value_1):
    """Controls the number of drop-downs available to choose sources"""
    if value_1 == 'Y':
        children = []
        for i in range(0, value):
            new_dropdown = dcc.Dropdown(
                id=f'''source_dropdown_{str(i)}''',
                options=['GOOG', 'FB', 'TDOC', 'FANG']
            )
            children.append(new_dropdown)
        print(children)
        print(type(children))
        return children

I keep running into a callback error. The drop down is constructed properly, so I am kind of confused as to why that error is being invoked.

dash.exceptions.InvalidCallbackReturnValue: The callback ..source_dropdown_container_output.children.. is a multi-output.
Expected the output type to be a list or tuple but got:
None. 

Any guidance or help is appreciated. All I am trying to do is add based on user input a dynamic number of drop downs to the layout.

Hello @UdayGuntupalli,

There’s an easy way to add arbitrary number of components in the layout - Pattern Matching Callbacks!
More info here - Pattern-Matching Callbacks | Dash for Python Documentation | Plotly

@atharvakatre,
I did look at that documentation. but could not get it to work, can you please provide a working example?

I found the answer I needed from stack overflow by Rob Raymond:

# Create callbacks
@app.callback(
    Output(component_id='source_dropdown_container_output', component_property='children'),
    [
        Input(component_id='drop_downs', component_property='value'),
        Input(component_id='sources_flag', component_property='value'),
    ]
)
def update_source_dropdowns(value, value_1):
    """Controls the number of drop-downs available to choose sources"""
    print("cb", value, value_1)
    if value_1 == ['Y']:
        children = []
        for i in range(0, value):
            new_dropdown = dcc.Dropdown(
                id=f'''source_dropdown_{str(i)}''',
                options=[{"label":v, "value":v } for v in ['GOOG', 'FB', 'TDOC', 'FANG']],
            )
            children.append(new_dropdown)
        print(children)
        print(type(children))
        return children