Pattern matching `MATCH` not working

Hey everyone,

I am having trouble to get pattern matching with MATCH working. My dash app has a list of buttons that gets dynamically updated after a file is uploaded. When pressing a button I want to read a specific file associated with a single button. For this I was trying to use pattern matching with MATCH in order to read the id of the pressed button. However this prevents my callback from being executed. Using ALL somehow works but with this I am not able to know which button was pressed. My app looks something like this:

app = Dash(__name__)

app.layout = html.Div(
    children=[
        html.Div(
            children=[
                html.Button(file, id={'type': 'saved-button', 'index': f'{file}'}) for file in files
            ],
            id='file_list'),

        dcc.Graph(
            id='fig'
            figure=fig
        ),

        dcc.Upload(
            id='upload-data'
        )
    ]
)

@app.callback(
        [Output('fig', 'figure'), Output('file_list', 'children')],
        [Input('upload-data', 'contents'), Input('upload-data', 'filename'), Input({'type': 'saved-button', 'index': ALL}, 'n_clicks')],
        [State('file_list', 'children'), State({'type': 'saved-button', 'index': MATCH}, 'id')],
        prevent_initial_call=True
    )
    def process(contents, filename, n_clicks, children, button_id):
        # Check if button was pressed or a file was uploaded
        if ctx.triggered_id != 'upload-data':
            file = f'{button_id["index"]}.parquet'
            data = pd.read_parquet(file)

            # Some processing and plotting fig

            return [fig, children]


        # Some processing in case a file was uploaded and creating fig

        # Saving data to disk and creating new button
        filename = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        df.to_parquet(f'{filename}.parquet')
        new_item = html.Button(
            filename,
            id={
                'type': 'saved-button',
                'index': filename
            }
        )

        children.append(new_item)

        return [fig, children]

Basically I am having problems with this piece of code: State({'type': 'saved-button', 'index': MATCH}, 'id'). When MATCH is replaced with all ALL at least the callback gets executed (although not with the intended logic). Thankful for any help and hints you might have :slight_smile:

Hello @Turing,

Using ALL is the way to go, since your output target is always the same.

The easiest way to know which button was pushed is ctx.triggered_id.index with pattern-matching. :grin:

2 Likes