How to make callbacks work when layout function depends on kwargs

Hi,

I have created a very simple multi-page Dash app based “Example: Simple Multi-Page App with Pages” found in https://dash.plotly.com/urls

.
├── app.py
└── pages
    ├── __init__.py
    ├── analytics.py
    └── home.py

Basically, the only change I’ve made is that pages.analytics now defines layout as a function with kwargs, rather than a static variable.

dash.register_page(__name__, path_template=f"/analytics/<analytics_arg>")

def layout(**kwargs):
    if "analytics_arg" not in kwargs:
        return None
    return html.Div(
        [
            html.H1("This is our {analytics_arg} Analytics page".format(**kwargs)),
            html.Div(
                [
                    "Select a city: ",
                    dcc.RadioItems(
                        options=["New York City", "Montreal", "San Francisco"],
                        value="Montreal",
                        id="analytics-input",
                    ),
                ]
            ),
            html.Br(),
            html.Div(id="analytics-output"),
        ]
    )

When I try to run this app, I get the familiar error:

ID not found in layout

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

Attempting to connect a callback Output item to component: "analytics-output" but no components with that id exist in the layout. 

It seems like dash calls all the pages’ layout functions when starting the app, even though the page has not yet been visited. So I can understand that this error occurs, because of the if "analytics_arg" not in kwargs: return None lines in the layout function. In this toy example, I could easily just render the un-parameterized layout when the function is called without any kwargs. But what if the layout really can’t be rendered properly without kwargs? What is the best solution for this issue? (I’d strongly prefer to not use the suppress_callback_exceptions=True approach.)

Code for this example is here: GitHub - odoublewen/dash-dynamic-layout-demo

This is related: Dynamically creating callbacks for a dynamically created layout but it’s an old thread, and I’m thinking it’s worth a new thread, to see what is the best approach, using recent Dash releases (I’m on 3.1.1)

Also, note that the callbacks do actually work, when the page is visited with a url kwarg. It’s just these error messages that I guess come from the initial call to layout()that I’m trying to squash. See screenshot:

There is no reason to avoid using `suppress_callback_exceptions=True. The purpose is to handle dynamic layouts :slight_smile:

1 Like

Thank you, that is useful feedback. I had somehow developed a prejudice against it, like it was a lazy thing to do. I didn’t realize it was “for” dynamic layouts. But now I see the pattern-matching callback docs all show suppress_callback_exceptions=True.

This opens up a lot of possibilities for my project, thanks!

1 Like