Best approach to accomodating multiple callbacks for an output

As far as I am aware it is still not possible to have multiple callbacks with the same output, but getting around this limitation means creating large callback with all the various inputs that might change a given output, which implies a lot of extra data potentially coming across this wire.

So, my questions are: (a) is there planned support for multiple callbacks with the same output in the near future? (b) if not, are there any recommended tips, tricks, best practices for getting around this? I have some ideas, but don’t want to re-invent the wheel if others have already found good ways to deal with this.

Thanks!

Hi @jauerb, yes this is something that I’ve also been quite frustrated about, but there is a good reason for this :-). If you had several callbacks that could write to the same prop and that had overlapping inputs, then which one should you trigger?

Therefore you need to have a single callback for a given output prop. However, here are a couple of tips:

  • you can use dash.callback_context to know which Input triggered the callback, as in the example in https://dash.plot.ly/faqs (How do I determine which Input has changed).
  • You can write the callback as a router calling different functions depending on which input changed, which is not that different from having several callbacks. For example
ctx = dash.callback_context
if not ctx.triggered:
    button_id = 'No clicks yet'
else:
    button_id = ctx.triggered[0]['prop_id'].split('.')[0]

if button_id == 'button1':
    return button1_updated(...)
elif button_id == 'button2':
    return button2_updated(...)
...
3 Likes

Thanks for this response. This is similar to what I was thinking about implementing. I will give it a shot and see how it goes.

After digging into this some more, I just want to mention that something I found crucial for this type of solution was to use dash.no_update to only update a subset of possible outputs from a callback.

2 Likes

Has this now been made possible? It is working for me when using Python 3.7 (and conda) but it doesn’t when I downgrade to Python 3.6.6 (using pip). in both I am using dash=1.18.1.
I can’t find anywhere the confirmation that this was changed so I am surprising it is working for me? maybe one of the installations is just suppressing the errors?

Hi, Back at this again … I looked at dash-extensions and Multiplexer Transform … I’d rather not go there. I have a case where there are two callbacks that I want to write to the same outputs. And these outputs are NEVER used as Input. Why can’t this be allowed?

I believe it is an ongoing discussion if/how to enable multiple callbacks to target an output, so it might be solved at some point. However, until that happens, i think that the MultiplexerTransform is a good option. What issues are you experiencing with it?

Thanks for the prompt response.

When I switch to

from dash_extensions.enrich import Output, DashProxy, Input, MultiplexerTransform, State

I get these messages on start up

C:\Users\wvw\AppData\Local\Programs\Python\Python39\lib\site-packages\dash_extensions\enrich.py:7: UserWarning:
The dash_core_components package is deprecated. Please replace
`import dash_core_components as dcc` with `from dash import dcc`
  import dash_core_components as dcc
C:\Users\wvw\AppData\Local\Programs\Python\Python39\lib\site-packages\dash_extensions\enrich.py:9: UserWarning:
The dash_html_components package is deprecated. Please replace
`import dash_html_components as html` with `from dash import html`
  import dash_html_components as html

However, it appears to work properly. These warnings are a concern about the support of these extensions.

The MWE (by Emmanuelle) for Left and Right clicks also demonstrates Outputs that are not used as Input – it gets the same warnings about components.

You will see those warnings if you use Dash 2.x.x due to the change in import syntax. It shouldn’t affect anything though, and I expect that it will take a significant amount of time before support for the old syntax is dropped. That being said, I expect to correct the imports relatively soon.