Is there a way to loop through a list of files and create DropdownMenuItems from the names?

I have been searching for this without avail. I have a list of files I would like to choose from to change the data within a data table. I have a DropdownMenu that I would like to add the list of files to so that a user can select the file they want to view.

I thought getting the list and running a for loop I could create the DropdownMenuItems but that causes the site to display the message “Error loading layout”. Here is the piece of code I thought would work:

files = [f for f in listdir(pathway) if isfile(join(pathway, f))]
items = [{
        dbc.DropdownMenuItem(i),
        } for i in files]

dropdown = dbc.DropdownMenu(
     direction="left",
     children=[items],
     label="Menu",
     color="info",
     ),
    
app.layout =dbc.Container( [
    html.Nav(navbar),
    dbc.Row([
        dbc.Col(dropdown,width=6, className="d-flex justify-content-end"),
        ],no_gutters=False, justify="between",),

...

Is there a different tactic to achieve this? I am sorry if this is a foolish question, I am quite new to python and Dash.

Hey, I think the problems are that you’re wrapping the dbc.DropdownMenuItem(i) with curly brackets in your list comprehension and passing that list as an item within a second list. The children argument for dbc.DropdownMenu should be a list of DropdownMenuItems (see: https://dash-bootstrap-components.opensource.faculty.ai/l/components/dropdown_menu).

If a,b,c are DropdownMenuItems, then the children of the DropdownMenu should be [a, b, c]. In your code the children of the DropdownMenu are [[{a},{b},{c}]].

files = [f for f in listdir(pathway) if isfile(join(pathway, f))]
items = [dbc.DropdownMenuItem(i) for i in files] #remove curly brackets on this line

dropdown = dbc.DropdownMenu(
     direction="left",
     children=items,  #remove brackets here
     label="Menu",
     color="info",
     ),
    
app.layout =dbc.Container( [
    html.Nav(navbar),
    dbc.Row([
        dbc.Col(dropdown,width=6, className="d-flex justify-content-end"),
        ],no_gutters=False, justify="between",),

Hope that helps.

2 Likes

You are my hero, that worked perfectly! Thank you!