Hi,
I added a loader using dcc.Loading into my output. My navbar is on my initial page and I’m loading layouts of a multi-page app. But when I load different layouts the Loader disables my Navbar and If I click an element on the navbar while loading, it loads that page after the current page is loaded. I want to have full control over my navbar and wantt the loader to load a different link in the navbar even when it is spinning. How can I do that Thank You.
You just need to have the children of your dcc.Loader
not contain your Navbar
.
2 Likes
It doesn’t contain my navbar. Can you show me a tried example that works? Thanks.
I took this example from Dash’s online tutorials, adding the sleep
function to aid in visualization and wrapping dcc.Loading
around the page-content
div.
import dash
import dash_core_components as dcc
import dash_html_components as html
from time import sleep
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div(
[
# represents the URL bar, doesn't render anything
dcc.Location(id='url', refresh=False),
# This code could be your navbar - unaffected by dcc.Loading
dcc.Link('Navigate to "/"', href='/'),
html.Br(),
dcc.Link('Navigate to "/page-2"', href='/page-2'),
# content will be rendered in this element
dcc.Loading(
html.Div(id='page-content')
)
]
)
@app.callback(dash.dependencies.Output('page-content', 'children'),
[dash.dependencies.Input('url', 'pathname')])
def display_page(pathname):
sleep(3)
return html.Div([
html.H3('You are on page {}'.format(pathname))
])
if __name__ == '__main__':
app.run_server(debug=True)
Hi,
I ran through the above code. So, when the alternate link is clicked the current page doesn’t stop it’s processing. Nor, it processes them one after the other. It processes them concurrently.(For this reason my navbar doesn’t show the new page when clicked because page is still executing my first script). I want the current page to stop it’s processing since my dashboard is CPU intensive and Load the new page in the middle of processing when clicked in the Navbar.
#here are the code changes I made to verify this in the terminal
import dash
import dash_core_components as dcc
import dash_html_components as html
from time import sleep
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div(
[
# represents the URL bar, doesn't render anything
dcc.Location(id='url', refresh=False),
# This code could be your navbar - unaffected by dcc.Loading
dcc.Link('Navigate to "/"', href='/'),
html.Br(),
dcc.Link('Navigate to "/page-2"', href='/page-2'),
# content will be rendered in this element
dcc.Loading(
html.Div(id='page-content',children=['This is default.'])
)
]
)
@app.callback(dash.dependencies.Output('page-content', 'children'),
[dash.dependencies.Input('url', 'pathname')])
def display_page(pathname):
sleep(1)
for i in range(500):
#here if other link is clicked, while the first
#loop is still executing, The next page is not loaded before it's completed
#also, both loops are processed concurrently
print(i)
print("complete")
return html.Div([
html.H3('You are on page {}'.format(pathname))
])
if __name__ == '__main__':
app.run_server(debug=True)
Summary:
- If, the current page that is returned using callback takes time to load, the dcc.loading(pre-loader) does’t stop processing the current page when a new link is clicked.
Need a way to stop the current layout to be processed and instead, load the new layout that is clicked in the middle of loading the first.
Any solution to this? seems like an important question, I’m having this issue too. One of my links in the navbar takes a while to load, so if I click a new link on the navbar, I don’t want to wait for it to load, and instead just kill it and go to the new page. But currently, it just waits until the first thing is loaded, then switches.