Attempting to connect a callback Input item but no component with that ID exists

This sounds great and I got some template running for porting my multi-page app to this format!

However, I have two callbacks in one of my pages and something weird happens with it.
My page renders totally fine, but I get these errors:

Attempting to connect a callback Input item to component:
  "variables2"
but no components with that id exist in the layout.

If you are assigning callbacks to components that are
generated by other callbacks (and therefore not in the
initial layout), you can suppress this exception by setting
`suppress_callback_exceptions=True`.
This ID was used in the callback(s) for Output(s):
  plot2.figure

My code for this page is, where i left the beginning of the code out where i read in the data etc.

first_card = dbc.Card(
    dbc.CardBody(
        [
                    html.H2("Recycled Material", className="card-title"),    
                    dcc.Graph(id='plot'),
                    dcc.Dropdown(
                            id='variables',
                                options=[{'label': i, 'value': i} for i in figs],
                                value=figs[0]
                            ),     
            
        ]
    )
)


second_card = dbc.Card(
    dbc.CardBody(
                [
                    html.H2("Virgin Material", className="card-title"),
                    dcc.Graph(id='plot2'),
                    dcc.Dropdown(
                            id='variables2',
                                options=[{'label': i, 'value': i} for i in figs],
                                value=figs2[0]
                            ),     

            
        ]

    )
)

cards = dbc.Row([dbc.Col(first_card, width=6), dbc.Col(second_card, width=6)],style={"margin-bottom": "15px", "margin-left":"15px", "margin-top":"15px", "margin-right":"15px"})



body = html.Div(
    [
       cards,
       ],


# className="mt-4",
style={'height':'100vh'},
)

@callback(
    Output('plot', 'figure'),
    [Input('variables', 'value')])
def update_graph(fig_name):
    if fig_name in data.columns:
        figure1 = px.line(data, x="Timestamp", y=fig_name)
        return figure1


@callback(
    Output('plot2', 'figure'),
    [Input('variables2', 'value')])
def update_graph2(fig_name):
    if fig_name in data2.columns:
        figure2 = px.line(data2, x="Timestamp", y=fig_name)
        return figure2


def Homepage_analytics():
    layout = html.Div([
    body
    ])
    return layout



def layout():
	return Homepage_analytics()

Should i just ignore that warning? Because i never got that warning before. The page renders fine btw everything works i only get that callback.

Hey Dasher @stefanbloemheuvel ,
Welcome to the Plotly Dash community.

I was thinking more about this error you’re getting. When I ran your code on a stand-alone one page app, I realized you would need two things:

  1. you need to add “app” right before the layout. like this:
def Homepage_analytics():
    app.layout = html.Div([
    body
    ])
    return layout
  1. Also, the layout needs to be executed by calling the function" layout().
def layout():
	return Homepage_analytics()

layout()

That said, in a multi-page app, this is not necessary if you’re calling your layout function in the main app page, especially if you have a recent version of Dash installed. I’ll message you to learn more about your code right now.

1 Like

@adamschroeder
I’m getting same behaviour in my multi-page app, pages render totally fine but I’m getting the same type of error from the callback function which is defined in one of the pages:

Attempting to connect a callback Input item to component:
“filter-dropdown”
but no components with that id exist in the layout.

If you are assigning callbacks to components that are
generated by other callbacks (and therefore not in the
initial layout), you can suppress this exception by setting
suppress_callback_exceptions=True.
This ID was used in the callback(s) for Output(s):
get-started-example-basic.rowData

Consider this project:

- app.py
- pages
   |-- home.py
   |-- table.py

The main app.py has a basic layout with a sidebar and the page_container:
app.layout = html.Div([sidebar, dash.page_container])

The “filter-dropdown” component is only defined in table.py.

Hey @igomisp welcome to the forums.

It’s pretty hard to diagnose without more information. Did you perhaps use @app.callback instead of @callback?

@AIMPED
No, I’m using @callback.

@callback(Output("get-started-example-basic", "rowData"), Input("dropdown", "value"))
def update_grid(selected_types):
    if selected_types is None or len(selected_types) == 0:
        print("No type selected")
        return entities
    else:
        print("Selected types: ", selected_types)
        return [entity for entity in entities if entity["type"] in selected_types]

I’ve been testing and it happens when using Variable Paths for one of my pages:

dash.register_page(__name__, path_template="/entity-details/<entity>")

But this page has no callbacks neither the objects which are triggering the ID errors.

I can paste all my code but I dont if it will help.

This usually helps a lot. Or better even if you can create a MRE.

1 Like

OK, I tried to summarize but it is almost my draft project code:

This is the structure of the project:

- app.py
- pages
   |-- entities.py # It create some dcc.Links with Variable Path: href=f"/entity-details/{entity['id']}"
   |-- entities-data.py  # Contains the callback which cause the error
   |-- entities-details.py # Template for Vairable Path pages
   |-- home.py # Homepage

Running the app, the server triggers the errors:

Attempting to connect a callback Output item to component:
“get-started-example-basic”
but no components with that id exist in the layout.

If you are assigning callbacks to components that are
generated by other callbacks (and therefore not in the
initial layout), you can suppress this exception by setting
suppress_callback_exceptions=True.
This ID was used in the callback(s) for Output(s):
get-started-example-basic.rowData

Attempting to connect a callback Input item to component:
“dropdown”
but no components with that id exist in the layout.
…

The app.py:

import dash
from dash import Dash, html
import dash_bootstrap_components as dbc

app = Dash(__name__, use_pages=True, external_stylesheets=[dbc.themes.LUMEN])

sidebar = html.Div(
    [
        html.H2("IoT platform", className="display-4", style={"textAlign": "center"}),
        html.Hr(),
        html.P("LINKS", className="lead"),
        dbc.Nav(
            [
                dbc.NavLink("Home", href="/", active="exact"),
                dbc.NavLink("Entities", href="/entities", active="exact"),
active="exact"),
            ],
            vertical=True,
            pills=True,
        ),
    ],
)

app.layout = dbc.Container([sidebar, dash.page_container])

if __name__ == "__main__":
    app.run(debug=True, port=1250)

Home page (home.py) it’s only a plain homepage:

import dash
import dash_bootstrap_components as dbc
from dash import html

dash.register_page(__name__, path="/")

dash.page_container.style = {
    "margin-left": "18rem",
    "margin-right": "2rem",
    "padding": "2rem 1rem",
}

layout = dbc.Container(html.P("Home page"))

This is the entity page (entities.py), which includes the links to Variable path pages:

import dash_bootstrap_components as dbc
import requests

import dash
from dash import dcc, html

ORION_HOST = "localhost"


def get_entities():
    # Context broker entities query
    newHeaders = {"fiware-service": "openiot", "fiware-servicepath": "/"}
    url = "http://" + ORION_HOST + ":1026/v2/entities"
    response = requests.get(url, headers=newHeaders)
    response.encoding = "utf-8"
    return response.json()


dash.register_page(__name__)

# Move to the right part of the sidebar
dash.page_container.style = {
    "margin-left": "18rem",
    "margin-right": "2rem",
    "padding": "2rem 1rem",
}


entities = get_entities()

table_header = [
    html.Thead(
        html.Tr(
            [
                html.Th("id"),
                html.Th("type"),
            ]
        )
    )
]


if len(entities) > 0:
    table_body = [
        html.Tbody(
            [
                html.Tr(
                    [
                        html.Td(
                            dcc.Link(
                                entity["id"],
                                href=f"/entity-details/{entity['id']}",
                                style={
                                    "color": "blue",
                                    "textDecoration": "underline",
                                },
                            )
                        ),
                        html.Td(entity["type"]),
                    ]
                )
                for entity in entities
            ]
        )
    ]

    table = dbc.Table(
        table_header + table_body, bordered=True, striped=True, color="light"
    )
else:
    table = html.P("No entities found")

layout = html.Div([html.P("Entities page"), table])

This is entities-data page (entitiy-data.py) which contains the callback. Render and works fine:

import dash_ag_grid as dag
import requests

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

dash.register_page(__name__)

dash.page_container.style = {
    "margin-left": "18rem",
    "margin-right": "2rem",
    "padding": "2rem 1rem",
}


def get_entities():
    # Context broker entities query
    newHeaders = {"fiware-service": "openiot", "fiware-servicepath": "/"}
    url = "http://" + "localhost" + ":1026/v2/entities"
    response = requests.get(url, headers=newHeaders)
    response.encoding = "utf-8"
    return response.json()


entities = [
    {
        **entity,
        **{
            key: value["value"] if isinstance(value, dict) else value
            for key, value in entity.items()
        },
    }
    for entity in get_entities()
]

types = list(set([entity["type"] for entity in entities]))


layout = html.Div(
    [
        dcc.Dropdown(
            id="dropdown",
            options=[{"label": type, "value": type} for type in types],
            value=[type for type in types],
            clearable=False,
        ),
        dag.AgGrid(
            id="get-started-example-basic",
            columnDefs=[
                {"field": "id"},
                {"field": "type"},
                {"field": "temperature"},
            ],
            className="ag-theme-balham",
            # columnSize="sizeToFit",
            defaultColDef={"resizable": True, "sortable": True, "filter": True},
            dashGridOptions={"pagination": True},
        ),
    ]
)


@callback(Output("get-started-example-basic", "rowData"), Input("dropdown", "value"))
def update_grid(selected_types):
    if selected_types is None or len(selected_types) == 0:
        print("No type selected")
        return entities
    else:
        print("Selected types: ", selected_types)
        return [entity for entity in entities if entity["type"] in selected_types]

And this is the page with Variable Path (entities-details.py). If I include this page in the project, I get the error from the callback. If this page is not in the project, the error is not triggered by the app:

import json

import dash_bootstrap_components as dbc
import requests

import dash
from dash import html

dash.register_page(__name__, path_template="/entity-details/<entity>")

ORION_HOST = "localhost"


def get_entities_details(entity):
    # Context broker entities query
    newHeaders = {"fiware-service": "openiot", "fiware-servicepath": "/"}
    url = "http://" + ORION_HOST + f":1026/v2/entities/{entity}"
    response = requests.get(url, headers=newHeaders)
    response.encoding = "utf-8"
    return response.json()


def display_entity_details(entity_details):
    if entity_details:
        table_header = [
            html.Thead(
                html.Tr(
                    [
                        html.Th("Attribute"),
                        html.Th("Value"),
                    ]
                )
            )
        ]

        table_body = [
            html.Tbody(
                [
                    html.Tr(
                        [
                            html.Td(attr),
                            html.Td(html.Pre(json.dumps(entity_details[attr]))),
                        ]
                    )
                    for attr in entity_details
                ]
            )
        ]

        table = dbc.Table(table_header + table_body, bordered=True, color="secondary")
        return table
    else:
        return html.P("No details available for this entity.")


def layout(entity):
    entity_id = entity
    entity_details = get_entities_details(entity)

    return (
        html.Div(
            [
                html.P(f"Details for Entity ID: {entity_id}"),
                display_entity_details(entity_details),
            ]
        ),
    )
    # return html.Div(html.P(f"Entity details page for {entity}")

@AIMPED @adamschroeder

I think I got what was going on.
In entities-details.py, the layout function has “entity” as an input variable but it had NO default value.

If I set this input as None, for example, the errors are not triggered by the app.

So I just changed:

def layout(entity=None):
    # No more changes
1 Like

Nice find, glad you figured it out. @igomisp