Dash Callbacks Not Updating Tab Content

I am trying to create an application homepage, with three full-page tabs. I am following the official documentation/tutorial here to get myself started. Specifically, I am following the ‘Styling the Tabs Component with CSS classes’.

My code is as follows:

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

app = Dash(__name__, title = 'title')
app.layout = html.Div([
    html.Div(
        className = 'application-header',
        children = [html.H1('title', className = 'application-header--title'),
                    html.H4('Subtitle', 
                            className = 'application-header--subtitle')]
    ),
    html.Br(),
    html.Div([
        dcc.Tabs(
            id = 'application-tabs',
            #value = 'explore',
            parent_className = 'hometabs',
            className = 'hometabs-container',
            children = [
                dcc.Tab(
                    label = 'Explore',
                    value = 'explore',
                    className = 'tab',
                    selected_className = 'tab-selected'
                ),
                dcc.Tab(
                    label = 'Publish',
                    value = 'publish',
                    className = 'tab',
                    selected_className = 'tab-selected'
                ),
                dcc.Tab(
                    label = 'About',
                    value = 'about',
                    className = 'tab',
                    selected_className = 'tab-selected'
                ),
            ]),
        ]),
    html.Div(id = 'tab-contents', children = [])
])

@app.callback(
        Output(component_id = 'tab-contents', component_property = 'children'), 
        [Input(component_id = 'application-tabs', component_property = 'value')]
        )
def render_content(tab):
    if tab == 'explore':
        return html.Div([
            html.H3('Explore content')
        ])
    elif tab == 'publish':
        return html.Div([
            html.H3('Publish content')
        ])
    elif tab == 'about':
        return html.Div([
            html.H3('About content')
        ])

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

However when running the app, the contents is not being properly rendered. For example, when I click on the tab ‘Explore’ the webpage should display the placeholder string ‘Explore content’. But cycling, through the tabs returns nothing. I have tried setting a default value in the upper level dcc.Tab(value = 'explore') but this didn’t work.

I am running the following versions and software:

  • dash 2.15.0
  • dash-core-components 2.0.0
  • dash-html-components 2.0.0
    *python 3.11.7

Coding in VSCode.

Here is the example webpage as a gif:

titleMozillaFirefox2024-02-0413-29-42-ezgif.com-video-to-gif-converter

Hi @ChickenWing and welcome to the Dash community :slightly_smiling_face:

I ran your example and it worked perfectly.

Maybe you have some CSS that is interfering?

btw, nice write-up of the issue - clear description, good minimal example :trophy:

Hi AnnMarie!

Thank you for your reply. May I ask what version of Dash and its required libraries you are running? I tried deleting the .css file from the /assets/ folder to remove any form of CSS and the tab content is still not rendering.

Here is a screenshot of the project directory:

Hi @ChickenWing

I’m using dash 2.15.0 and python 3.10
Are you using conda? I wonder if that might be the problem – but I’m not sure since I don’t use conda.

Are you having any issues with any other examples? Did you try running the examples from the Dash in 20 minutes tutorial?

Hi @AnnMarieW

You are correct. I pointed VSCode to use the Python interpreter in the custom conda environment.
I tried running the code as suggested from the HTML and CSS section of the Dash in 20 minutes tutorial.

The CSS seems to have customized the output to some degree, however the data is not being loaded into the barchart in response to the callback for selecting the buttons ‘pop’, ‘lifeExp’, or ‘gdpPerCap’.

Here is a gif of me interacting with the tutorial webpage:
DashMozillaFirefox2024-02-0421-43-59-ezgif.com-video-to-gif-converter

OK, looks like the same issue. I haven’t seen this before. I also use Pycharm rather than VSCode.

Maybe someone else here can jump in with suggestions?

Sorry I can’t be more helpful today :slightly_frowning_face:

@AnnMarieW Thank you for all your help and welcoming me to the community. Any friendly input is always nice to hear :smile:

Do you think it is because I am running the app without the reloader? As in:

if __name__ == "__main__":
    app.run(debug = True, use_reloader = False)

The reloader shouldn’t make a difference. It’s just a nice debugging feature because it will restart the app when you change the code. But you could always try changing it to True and see what happens :slight_smile:

Hey there, is the content of your tabs on a separated python scripts, independent of your app.py scripts ?

Hi @Ideco

The content is in the app.py script. It should be loaded in response to callback by the render_content function, which appends new HTML to the children property of the HTML Div with id tab-content.

Weirdly as part of debugging I surrounded the decorator and render_content function in quotes as to not execute as Python code, e.g;

'''
@app.callback(Output(...), [Input(...)])
def render_content(tab):
    *function logic to check tab value and return content*
'''

And the webpage is the same as that in the gif of the first post, implying the render_content function isn’t being called/triggered properly.

Hi all!

I found the problem. It turns out it is a problem with VSCode, it doesn’t execute the @callback decorator when using the usual shift + Enter to run code. However calling python app/app.py in the terminal solves this issue.

Thanks for everyone’s input and for welcoming me to the community!

3 Likes