In my multi-page app I would like to share storage, or at least, I want to click a button and have that effect on the layout of the next page. That’s what I would like to accomplish, so if I go to a settings page and click I want a pink background on all pages, I want that to happen. I don’t per se use just ONE store, but I would like to be able to share some state by sharing some stores.
The thing is that the initial callbacks seem to be fired only the first time, but I guess I already found the solution. Still there are some questions which need to be answered. This is my code for two pages, which share the same store and state id’s:
products_bp = DashBlueprint()
products_bp .layout = html.Div([
Store(id="my_storage", storage_type="session"),
html.Button("Click me!", id="my_id"),
html.Div(id="log"),
])
# Update the store
@products_bp .callback(
Output("my_storage", 'data'),
Input("my_id", "n_clicks"),
State("my_storage", 'data'))
def on_click(n_clicks, data):
if n_clicks is None:
raise PreventUpdate
# Give a default data dict with 0 clicks if there's no data.
data = data or {'clicks': 0}
data['clicks'] = data['clicks'] + 1
return data
# Update the HTML
@products_bp .callback(
Output("log", "children"),
Input("my_storage","'modified_timestamp"),
State("my_storage", 'data'))
def on_data(ts, data):
if ts is None:
raise PreventUpdate
data = data or {}
return f"Amount of clicks: {data.get('clicks', 0)}"
On page load, initial callbacks are fired, but as soon as I navigate to another page (there is no refresh by the way, just like any other single page app), the Amount of clicks: {data.get('clicks', 0)}
disappear.
I figured I had two options:
- use a different storage for each page, but that’s what I don’t want as described above
- remove the
ts is None: raise PreventUpdate
from the last callback.
But with the last option, I’m not sure if that can cause any strange behavior? I believe it is kinda odd that the timestamp is set on page load, but not after a page switch…
And perhaps one extra question: it seems to take like a half of a second for “Amount of clicks: {data.get(‘clicks’, 0)}” to show up, not sure if I can add a pageloader to have the experience the message is just there, instantly, or there are ways to speed things up?