Hey everyone! My first post here as I want some expert advise on callbacks. Please take a look at the video below where I show the web app I am working on and what is the issue.
It is a 7 min video, so I apologize, I start explaining what I am creating and at the end I explain the issue…
Usually you get help faster, if you describe the problem in a concise way and if you add some sample code which lets us replicate the error you are facing.
There is no error message. Basically I created a Web App that allows users to configure Dash dashboards without writing code. Issue is if an update is done to a chart or any widget from the dashboard, the callback stops working.
Is there a way to reset all callbacks without restarting the application?
If the above is not possible, can I update an already registered callback?
Is the above is not possible, any idea to allow Dashboards to be updated without the needs to restart the application?
@AIMPED thanks. only the Dasboards are Dash, all the rest are standard HTML, CSS and JS.
A callback is registered with a set of inputs and outputs. If those outputs or inputs are updated while the application is still serving, the callbacks won’t be called again… it kinda breaks.
In the video I explain my idea, and that is to have a set of user interfaces that allows the user to create and update dashboards (layouts) without the need to write python code for it. But right now if the users updates or creates a new Widget (I call a Widget basically a chart figure for example), it will break the callbacks.
The solution I implemented works, but I dont like it… my solution is to have an integer that increments every time an update happens and recreate the dashboard inputs and outputs with a new id (that id will contain the integer mentioned). With that I can register new callbacks and the dashboards are updated live (I mean, if a new chart is added, there is no need to restart the application).
Here is the string to be used to initialize a new output. Note the Dashboard.updates in the id parameter:
widget_class: str = f"dcc.{widget.widget_class}(id = '{self.id}-{widget.code}-{Dashboard.updates}|', {','.join([f'{k} = {v}' for k, v in widget.parameters])})"
Not sure how you register new callbacks, since they are registered at app start. But I used the Pattern Matching callbacks. Basically the components dont have a string id, but a dictionary.
That way, you can yous the same callback to update different components according to the Matches.
@simon-u thanks! I tried to use that but it doesn’t work as well on my use case as everything can change in a layout.
I think I am gonna stick with my solution, basically recreating the whole layout and assigning a new id to the inputs and outputs. This means many callbacks will exist in the application that will never be hit until the app restarts, but it is what it is.
When I am done with my implementation I will record a new video to show how flexible the solution is.