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}")