Skip to content

Callback interaction #1561

@joel314

Description

@joel314

Hi,

I am using dash version 1.19.0 and I am trying to build a data table having:

  1. two columns: the first one is editable and the second one is updated based on the first one,
  2. a button that adds new rows to the table.

I can make (1) work and I can make (2) work but I am not able to make (1) and (2) work at the same time. When both callbacks are defined, the 1st callback is never triggered.

Based on the documentation:

I created the minimal example below:

import dash
from dash.dependencies import Input, Output, State
import dash_table
import dash_html_components as html
from loguru import logger

app = dash.Dash(__name__)
app.config['suppress_callback_exceptions'] = False


app.layout = html.Div([
    dash_table.DataTable(
        id='table',
        columns=[
            {'name': 'Input Data', 'id': 'input-data', 'editable': True},
            {'name': 'Input Squared', 'id': 'output-data', 'editable': False}
        ],
        data=[{'input-data': i} for i in range(5)],
        editable=True,
        row_deletable=True
    ),
    html.Button('Add Row', id='add-row-button', n_clicks=0),
])

# Problem 1: This callback below is never triggered. When I click on the button, the update_columns is
# triggered instead.
@app.callback(
    Output('table', 'data'),
    Input('add-row-button', 'n_clicks'),
    [State('table', 'data'),
     State('table', 'columns')])
def add_row(n_clicks, rows, columns):
    logger.debug("Adding row")
    if n_clicks > 0:
        rows.append({c['id']: '' for c in columns})
    return rows


@app.callback(
    Output('table', 'data'),
    Input('table', 'data_timestamp'),
    State('table', 'data'))
def update_columns(timestamp, rows, x):
    # Problem 2: I have to add a 3rd argument, otherwise I get this error:
    # TypeError: update_columns() takes 2 positional arguments but 3 were given
    logger.debug("Updating column")
    for row in rows:
        try:
            row['output-data'] = float(row['input-data']) ** 2
        except:
            row['output-data'] = 'NA'
    return rows


if __name__ == '__main__':
    app.run_server(debug=True, port=1234)

callback_graph

It is like if dash is trying to re-use the same Input and States from add_row for update_columns (hence the need to have a 3rd argument) and is ignoring add_row. If I swap the order of the definitions of the 2 functions, none of them is triggered.

Any help would be appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions