✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🧬 Learn how to build RNA-Seq data apps with Python & Dash. Register for the May 20 Webinar!

How do we repeat element id in multi-page apps?

We just started using Dash for our dashboard requirements. Our plan is that individual teams shall develop their dashboard py file independently and centrally we shall integrate it into single application by calling them from index.py.

Our file structure is as below
‘’’

  • app.py - index.py - apps |-- init.py |-- app1.py |-- app2.py |-- app3.py |-- app4.py |-- app5.py

where app1 to app5 are written independently. index.py shall have the home page content and links to other app1-5.

One issue we face is that, sometimes different developers tend to use same id name in their py files. That is, user1 working on app1.py and user2 working on app2.py uses same id for object, like say dbc.Checklist. In such scenarios, while loading the home page I am getting the error

‘’’
Duplicate callback outputs
4:03:55 PM
In the callback for output(s):
chkLstState.value
Output 0 (chkLstState.value) is already in use.
Any given output can only have one callback that sets it.
To resolve this situation, try combining these into
one callback function, distinguishing the trigger
by using dash.callback_context if necessary.
‘’’

Can someone point to an example how we can handle such a requirement? Thanks.

Regards,
Karthik

This is a classic problem. In a utils module, I create this “id function factory”:

def id_factory(page: str):
    def func(_id: str):
        """
        Dash pages require each component in the app to have a totally
        unique id for callbacks. This is easy for small apps, but harder for larger 
        apps where there is overlapping functionality on each page. 
        For example, each page might have a div that acts as a trigger for reloading;
        instead of typing "page1-trigger" every time, this function allows you to 
        just use id('trigger') on every page.
        
        How:
            prepends the page to every id passed to it
        Why:
            saves some typing and lowers mental effort
        **Example**
        # SETUP
        from system.utils.utils import id_factory
        id = id_factory('page1') # create the id function for that page
        
        # LAYOUT
        layout = html.Div(
            id=id('main-div')
        )
        # CALLBACKS
        @app.callback(
            Output(id('main-div'),'children'),
            Input(id('main-div'),'style')
        )
        def funct(this):
            ...
        """
        return f"{page}-{_id}"
    return func

Then follow the example on each page and you’ll have unique IDs and a clear paradigm for everyone to use.

2 Likes

Thanks Russell for the detailed reply with an elegant solution. This worked great.