I’m having trouble converting a fairly simple React concept into Dash – I need to set the state before AND after a long running task. I have a dashboard where a button initiates “long running task”, the completion of which populates the dashboard. I would like to display a loading message in the meantime. In React I would set an isLoading property and update the state accordingly upon completion of “long running task”. In dash, I am attempting to replicate this with a hidden “status” div that toggles between “ready/loading”. The flow I would like is:
User clicks button to start process
Status div changes to “loading”
The loading screen is listening to the Status div and updates to be visible
The long running process begins
After the process finishes, the status div is updated to ready
Loading animation becomes invisible
Resulting dashboard becomes visible
My callback structure:
- Status div listens to button click (sets status to “loading”) and graph data to set to know when completed (set “ready”)
- graph data listens to status div to know when to begin the calculation
- loading screen listens to status div to know when to display and to graph data to know when to stop
However, this causes a circular dependency error because button → status → graph → status → graph
Is there a different pattern that can accomplish this in Dash?
As a quick workaround, your global dash app container get the CSS class
._dash-loading-callback when updating its content. You might have look at 📣 Dash Loading States to see if you could use this.
Otherwise, if I understand your app correctly, I would create following callbacks:
- Input: button, n_clicks
- Output: status_div, children
- Input: button, n_clicks
- Output: graph, figure
- Input: graph, figure
- Output: status_div, children
This way, 1 and 2 are fired together, and 3 is fired when 2 is completed. You would put both “loading” and the animation in
status_div (hard to be more explicit without some proper MWE).
(This might be a bit more difficult as 1 and 3 have the same output — and I think I remember you cannot have two callbacks with the same output (for the moment). If it’s actually the case, you should create one global callback with both 1 & 3 triggers, retrieve which trigger fired the callback, and set output accordingly.)
You can show/hide the graph using CSS (
display: none or
visibility: hidden, depending on what you want to achieve). You would then need a 1bis and 3bis callbacks that have the same inputs, and use
graph, style (or — preferably —
graph, className if you use proper CSS).
You pretty much have described what I have currently implemented. As you mentioned, 1 + 3 have to be combined. An issue I have found with having 1 and 2 is that I am unable (I think) to control the order that the callbacks fire, so what I encounter is that once the start button is clicked the loading screen does not appear until after the long running process has completed. This can equivalently be seen by changing the style of some other element onclick with the same button that triggers the long running task.
I get it now. IMHO, what you are looking for is: “how to define the fire order for callbacks having the same trigger” (I assumed they would have been fired simultaneously).
I’ve looked a bit around and it seems that if two callbacks are to be triggered “simultaneously”, there is no way to define which will actually be fired first. (Note that more experienced user might have more insights on this.)
To get a clearer view of the callback, you can have a look at Dash callback chain (kudos to @OliverBrace). Yet this doesn’t solve your issue.
Note: this is a WIP: I just realize we’re facing the same issue (two callbacks fired at the same time)
Here is a logic way that could work:
You have to create a hidden
placeholder_div. When you click on the button, you will update the content of this
placeholder_div. You make sure you actually change it by reading its content using a
In case it is useful for somebody, I managed to workaround circular dependencies to implement a progress bar during the processing of the data. In my case, the final data is a table inside a Div,
enclosing_div. My solution is based on displaying the progress bar in the same Div as the final table: this removes the need to delete/hide it when it is no longer needed. When ready and displayed the table replaces it. The callback structure I use to achieve this is the following:
In the layout I add 2
pb_saved_indicator, with their
data property initialized to 0.
The main callback, doing the real work, is fired by a change of
pb_indicator value, one of its
Input or one of the other inputs that depend on your application. It also receives as a
pb_saved_indicator. This callback is fired twice when data processing is required. Each time the value of
pb_indicator is comparated with
- If they are equal, it means it is the first execution and the progress bar is displayed in
enclosing_div, as well as a
dcc.Interval configurer to run once (
dcc.Interval will be in charge of triggering the current callback a second time by incrementing
pb_indicator. This is done by returning something like
component = html.Div([
create_progress_bar, # A function you need to write to initialize the main progress bar is the usual way
dcc.Interval(id='trigger-interval', n_intervals=0, max_intervals=1, interval=500)
pb_indicator value is greater than
pb_saved_indicator, the data processing is started and at the end of it,
pb_saved_indicator is updated with
The callback for the
dcc_interval that writes in
pb_indicator the value of
pb_saved_indicator + 1.