Hello,
I have come across a possible bug (or complete lack of understanding on my part) with dcc.Location. Is there anything I’m doing wrong? In the real app I need this to reload the user-generated data in tables when pages are changed.
What is happening:
A callback in a multi-page app only gets triggered by a url change if the callback has a single output. If there are two outputs, the callback never happens.
What should be happening:
A callback that is triggered by a url change should always fire, independent of the number and type of outputs.
Simple reproducible example:
In the following simple, reproducible example app2 works correctly, app1 does not. The only difference between both apps is that the callback in app2 has a single output (updating a label with the pathname), while the callback in app1 has two outputs (updating two labels with the pathname).
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
import app1
import app2
app.layout = html.Div([
dcc.Location(id='url', refresh=True),
html.Div(id='page-content')
])
index_page = html.Div([
html.Div([
html.H1('Index Page'),
dcc.Link('Go to Page 1', href='app1'),
dcc.Link('Go to Page 2', href='app2'),
], className='subpage')
], className='page')
@app.callback(Output('page-content', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
print('index:', pathname)
if pathname == '/app1':
return app1.layout
elif pathname == '/app2':
return app2.layout
else:
return index_page
if __name__ == '__main__':
app.run_server(debug=True)
app1.py
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
from app import app
layout = html.Div([
html.Div([
html.H1('Page 1'),
dcc.Link('Go to Index', href='index_page'),
dcc.Link('Go to Page 2', href='app2'),
html.H3(id='label_page1', children='none'),
html.H3(id='label2_page1', children='none'),
], className='subpage')
], className='page')
@app.callback([Output('label_page1', 'children'),
Output('label2_page1', 'children')],
[Input('url', 'pathname')])
def update_sample_info(pathname):
print('page1:', pathname)
return(pathname, pathname)
app2.py
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
from app import app
layout = html.Div([
html.Div([
html.H1('Page 2'),
dcc.Link('Go to Index', href='index_page'),
dcc.Link('Go to Page 1', href='app1'),
html.H3(id='label_page2', children='none')
], className='subpage')
], className='page')
@app.callback(Output('label_page2', 'children'),
[Input('url', 'pathname')])
def update_sample_info(pathname):
print('page2:', pathname)
return(pathname)
Version
I am using python 3.6 and dash 1.9.0 on openSUSE Leap15.1