How to delete dict of nested list by patch()?

Hi,
Thanks for the great work!
I want to implement dropdown value interactive with tabs .It’s ok for adding new tab by using patch().append function.However, I just confuse how to delete tab when delete selected value in dropdown component?
Is there anyone have ideas about this question?
My code is as follows:

import dash
from dash import dcc, html, Patch
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
import pprint
import uuid
from dash.dependencies import Input, Output, State, ALL, MATCH


app = dash.Dash(__name__)

app.layout = html.Div([
    html.Div(
        [
            dcc.Dropdown(
                id='dropdown',
                options=[
                    {'label': 'tab1', 'value': 'tab1'},
                    {'label': 'tab2', 'value': 'tab2'},
                    {'label': 'tab3', 'value': 'tab3'},
                    {'label': 'tab4', 'value': 'tab4'},
                    {'label': 'tab5', 'value': 'tab5'},
                    {'label': 'tab6', 'value': 'tab6'},
                    {'label': 'tab7', 'value': 'tab7'},
                ],
                multi=True,
            ),
        ],
        style={
            'padding': '50px',
        },
    ),

    dcc.Store(id='tabs-store'),  

    html.Div(
        [
            dcc.Tabs(
                id='tabs_example',
                children=[]
            )
        ],
        style={
            'padding': '50px',
        },
        id='tab_area_div'
    ),

    html.Div(id='content')
])


@app.callback(
    Output('tabs_example', 'children'),
    Output('tabs_example', 'value'),
    Input('dropdown', 'value'),
    Input('tabs_example', 'children'),
    prevent_initial_call=True
)
def test(value, tab_children):
    tab_items = Patch()
    for i in value:
        if i not in [t['props']['value'] for t in tab_children]:
            tab_items.append(
                dcc.Tab(
                    label=i,
                    value=i,
                    children=html.Div([
                        html.H3('Tab content {}'.format(i))
                    ])
                )
            )
    return tab_items, i


if __name__ == '__main__':
    app.run(debug=True, port='8070')

Thanks in advance :grinning:

Hey @atam welcome to the forums.

Is there any reason for using Patch() ? You could do something like this:

@app.callback(
    Output('tabs_example', 'children'),
    Input('dropdown', 'value'),
    prevent_initial_call=True
)
def test(current_selection):
    tab_items = []
    for i in current_selection:
        tab_items.append(
            dcc.Tab(
                label=i,
                value=i,
                children=html.Div([
                    html.H3('Tab content {}'.format(i))
                ])
            )
        )
    return tab_items

Thanks for your reply :melting_face:, however,I want to use partial update or delete,so how to use Patch() delete function?

Fair enough, but I still would be highly interested to know the reason for that!

Anyways, the thing is that you have to understand Patch() as an instruction of how to alter the component you are trying to change. So if you want to delete an item of the component children, you’ll have to know the index of this item first .

import dash
from dash import dcc, html, Patch, Input, Output


# helper function
def get_index(search_in, search_for):
    try:
        index_value = search_in.index(search_for)
    except ValueError:
        index_value = -1
    return index_value


app = dash.Dash(__name__)

app.layout = html.Div(
    [
        html.Div(
            [
                dcc.Dropdown(
                    id='dropdown',
                    options=[
                        {'label': 'tab1', 'value': 'tab1'},
                        {'label': 'tab2', 'value': 'tab2'},
                        {'label': 'tab3', 'value': 'tab3'},
                        {'label': 'tab4', 'value': 'tab4'},
                        {'label': 'tab5', 'value': 'tab5'},
                        {'label': 'tab6', 'value': 'tab6'},
                        {'label': 'tab7', 'value': 'tab7'},
                    ],
                    multi=True,
                )
            ],
            style={'padding': '50px'},
        ),
        html.Div(
            [
                dcc.Tabs(
                    id='tabs_example',
                    children=[]
                )
            ],
            style={'padding': '50px'},
            id='tab_area_div'
        ),
        html.Div(id='content')
    ]
)


@app.callback(
    Output('tabs_example', 'children'),
    Input('dropdown', 'value'),
    Input('tabs_example', 'children'),
    prevent_initial_call=True
)
def update_tabs(current_selection, current_tabs):

    # Patch() instance
    tab_items = Patch()

    # get tab name
    current_tabs = [tab['props']['value'] for tab in current_tabs]

    # create sets
    selected_set = set(current_selection)
    tabs_set = set(current_tabs)

    # figure out what to do
    keep = selected_set & tabs_set
    delete = tabs_set ^ keep
    new = keep ^ selected_set

    # find the indices of the tab names to delete in children, sort
    del_indices = sorted([get_index(current_tabs, item) for item in delete])

    # filter indices
    del_indices = [i for i in del_indices if i != -1]

    # alter Patch() instance, delete children at index
    if del_indices:
        for i in del_indices:
            del tab_items[i]

    # alter Patch() instance, create new tabs depending on selection
    for i in new:
        tab_items.append(
            dcc.Tab(
                label=i,
                value=i,
                children=html.Div(
                    [
                        html.H3('Tab content {}'.format(i))
                    ]
                )
            )
        )
    return tab_items


if __name__ == '__main__':
    app.run(debug=True, port=8070)

That’s what i want to realize, thank you so much!!! :+1: