Black Lives Matter. Please consider donating to Black Girls Code today.

Callbacks stop working in multipage app if there's multiple Outputs

Hi everyone!

I’ve recently discovered that if I create a multipage app according to https://dash.plotly.com/urls and some of my apps pages contain a callback with multiple outputs, it doesn’t work.

Here is my example code:

app.py:

import dash

app = dash.Dash(__name__)
server = app.server
app.config.suppress_callback_exceptions = True

index.py:

import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

from app import app
from apps import master, detail


app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content')
])


@app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/':
        return master.layout
    elif pathname == '/detail':
        return detail.layout
    else:
        return '404'

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

master.py:

import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

from app import app

items = [f'item{i}' for i in range(1,10)]

layout = html.Div([
    html.H3('Master'),
    html.Div([
        dcc.Link(children=item, href=f'/detail?id={item}') for item in items
    ], id='master-items'),
])

detail.py that works:

import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

from app import app

layout = html.Div([
        html.H3(id='detail-title'),
        html.H3(id='detail-title2'),
])

@app.callback(Output('detail-title', 'children'),
              [Input('url', 'search')])
def update_detail_title(query):
    return 'aaaa ' + query

detail.py that doesn’t work:

import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

from app import app

layout = html.Div([
        html.H3(id='detail-title'),
        html.H3(id='detail-title2'),
])

@app.callback([Output('detail-title', 'children'), Output('detail-title2', 'children')],
              [Input('url', 'search')])
def update_detail_title(query):
    return 'aaaa ' + query, 'bbb'

Isn’t it a bug?

that looks like a bug, but also your multiple output callback is missing an “else” that should return two values. currently it is implicitly returning a single None value. so, it’s a bug inn that we should fail more gracefully, but explicitly returning two None values may fix the issue.

Yes you’re right. I’ve removed that ‘if’ in my example. Anyway it’s not working with or without it.

Hi guys,

I found this thread as I was trying to figure out why my callbacks weren’t firing once I transitioned my app to be multi-page using dcc.Lcation and dcc.Link. The callbacks that weren’t working were the one’s with multiple outputs, splitting these into single output callbacks got it all working again. So thanks for bringing this to my attention!

I know I’m not sharing a code snippet to explain this properly but thought I’d mention I’d encountered this potential bug too.