Black Lives Matter. Please consider donating to Black Girls Code today.

Error loading layout if use specific Input component

Hello together,

I am using a callback method like:

@app.callback(Output('datatable-filtered-Objects', 'selected_rows'),
          [Input('selected_objects', 'children')],    
          )
def do_somethink(value):
 #do somethink
return []

the selected_objects will set by another method (if the failure occures, this method will never entered):

@app.callback(Output('selected_objects', 'children')
[   Input('area', 'clickData'),
    Input('datatable-filtered-Objects', 'selected_rows')]


def update_selected_object_ids(clickData, selected_rows, rows, selected_objects):
if selected_objects is None:
input = pd.DataFrame([])
else:
input = pd.read_json(selected_objects, orient='split') 
...
return pd.DataFrame(object_ids).to_json(date_format='iso', orient='split')

the html component is defined like this:

html.Div(id='selected_objects',
style={'display': 'none'},
children=[]
),

I get an “Error loading layout” failure in the browser. The reason is the Input of selected_objects. The debugger never entered the method body. I assume that the value of children could be None. I am not a frontend or python developer and this frustrated me because I don’t get any additional information about the reason and I haven’t the time to go deep into the mechanics.

I will be happy if anyone has some information about the failure and how I can handle this.

You have two Output in your example.

sry, the post was under construction as you respond XD

I meant the Output is there two time.

Oh, thx. This was a copy paste problem to the forum. I have fixed that. The failure occures to the input component, if I use another input component, all will rendered

You got two inputs but 4 arguments, it have to be the same number of arguments as the number of Input/State.

Thy for your response. The failure doesn’t depends on the count of the input parameter. I created a minimal example code that you can reproduce the failure:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Event, Input, State
import dash_table as dt

app = dash.Dash(__name__)

app.layout = html.Div([
html.Div([
    html.Div([
        html.H3('Area'),
        dcc.Graph(
            id='area',
        ),

    ]),

    html.Div([
        dcc.Graph(id='object-travel-in-area'),
        dcc.Graph(id='relationship-from-an-object'),
    ]),
], style={'columnCount': 2}),

html.Div(children=[
    html.H3(children='Matching Objects'),
    dt.DataTable(
        sorting_type="multi",
        row_selectable="multi",
        row_deletable=True,
        selected_rows=[],
        id='datatable-filtered-Objects'
    ), html.Div(id='datatable-interactivity-container')
]),
html.Div(id='selected_objects',
         style={'display': 'none'},
         children=[]
         ),
html.Div(id='filtered_objects',
         style={'display': 'none'},
         children=[]
         )
], style={"height": "100vh"})


@app.callback(Output('datatable-filtered-Objects', 'selected_rows'),
          [Input('selected_objects', 'children')],     )
def update_selected_object_table(selected_objects_json):
return []


@app.callback(
Output('selected_objects', 'children'),
[
    Input('area', 'clickData'),
    Input('datatable-filtered-Objects', 'selected_rows'),
]
)
# if I clicked on the graph or on the table, the selected_objects should updated
def update_selected_object_ids(dataA, dataB):
return []  # This line will never entered though the debuger


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

Hi

I think I saw a post yesterday about your issue, and Chris explained it wasn’t implemented yet.
What your code is doing is basically an infinite loop of callbacks.

Callback1:
OUTPUT = ‘datatable-filtered-Objects’, ‘selected_rows’
INPUT = ‘selected_objects’, ‘children’

Callback2:
OUTPUT = ‘selected_objects’, ‘children’
INPUT = ‘datatable-filtered-Objects’, ‘selected_rows’ (+ another one)

So callback1 triggers callback2, which trigger callbacks1, etc.

One way to avoid such loop would be to change your callback2. Since you have 2 inputs, you can change the ‘datatable-filtered-Objects’ from Input to State, and the loop will be broken. However, callback2 will only be triggered when ‘area’, ‘clickData’ is clicked

New Callback2:
OUTPUT = ‘selected_objects’, ‘children’
INPUT = ‘area’, ‘clickData’
STATE = ‘datatable-filtered-Objects’, ‘selected_rows’

1 Like

Thank you, that solution works

1 Like