Plotly dash - multi button index trigger issue

@app.callback(
    [Output('page-content', 'children'),
     Output('dashboard-selection-modal', 'is_open', allow_duplicate=True),
     Output('dashboard-buttons', 'children')],
    [Input('url', 'pathname'), Input('login-button', 'n_clicks')],
    [State('username', 'value'), State('password', 'value')],
    prevent_initial_call=True
)
def display_page(pathname, n_clicks, username, password):
    if not ctx.triggered:
        raise PreventUpdate
    trigger_id = ctx.triggered[0]['prop_id'].split('.')[0]
    if trigger_id == 'login-button' and n_clicks:
        user = dao.authenticate_user(username, password)
        if user:
            login_user(user)
            dashboards = dao.get_dashboards_by_user(current_user.id)
            if len(dashboards) == 1:
                dashboard_module = load_dashboard_module(dashboards[0][1])
                if dashboard_module:
                    return blank_layout, False, []  # Close modal and load the single dashboard immediately
            else:
                dashboard_buttons = [html.Button(dashboard[0], id=json.dumps({'type': 'dashboard-button', 'index': dashboard[1]}), n_clicks=0,
                                                 style={'backgroundColor': '#2c2c2c', 'color': login_color, 'border': f'1px solid {login_color}', 'borderRadius': '5px', 'padding': '10px', 'margin': '10px 0', 'width': '100%', 'cursor': 'pointer'}) for dashboard in dashboards]
                print(f"Dashboard buttons: {dashboard_buttons}")  # Debugging line
                return blank_layout, True, dashboard_buttons  # Replace with blank_layout and open modal on successful login
        return login_layout, False, []
    if pathname in [None, "/", "/login"]:
        return login_layout, False, []
    return 'Please login to view this page.', False, []


@app.callback(
    [Output('dashboard-content', 'children', allow_duplicate=True),
     Output('dashboard-selection-modal', 'is_open')],
    [Input({'type': 'dashboard-button', 'index': ALL}, 'n_clicks')],
    prevent_initial_call=True
)
def render_dashboard_content(n_clicks):
    if not ctx.triggered:
        raise PreventUpdate
    print("render_dashboard_content")  # Debugging line
    trigger_id = json.loads(ctx.triggered[0]['prop_id'].split('.')[0])
    dashboard_name = trigger_id['index']
    print(f"Dashboard button clicked: {trigger_id}")  # Debugging line
    print(f"Dashboard name extracted: {dashboard_name}")  # Debugging line

In the above example of two function. In the display_page function inside my app.py I have the following button generation:

dashboard_buttons = [html.Button(dashboard[0], id=json.dumps({'type': 'dashboard-button', 'index': dashboard[1]}), n_clicks=0,
                                                     style={'backgroundColor': '#2c2c2c', 'color': login_color, 'border': f'1px solid {login_color}', 'borderRadius': '5px', 'padding': '10px', 'margin': '10px 0', 'width': '100%', 'cursor': 'pointer'}) for dashboard in dashboards]

When I push one of these buttons, nothing happens. The render_dashboard_content function never gets triggered with its

[Input({'type': 'dashboard-button', 'index': ALL}, 'n_clicks')]

can anyone tell me what i am doing wrong? I think I’m either formatting it wrong or it’s an index issue… any help would be greatly appreciated.

Hello @jarelan,

You shouldnt be using json.dumps here:

dashboard_buttons = [html.Button(dashboard[0], id=json.dumps({'type': 'dashboard-button', 'index': dashboard[1]}), n_clicks=0,
                                                     style={'backgroundColor': '#2c2c2c', 'color': login_color, 'border': f'1px solid {login_color}', 'borderRadius': '5px', 'padding': '10px', 'margin': '10px 0', 'width': '100%', 'cursor': 'pointer'}) for dashboard in dashboards]

That should clear it up.