Need help from Dash Experts

I’m working on a Developing Dash app that has many pages for each page many tabs for each tab it has a reload button once you click it, it’ll fetch the data that’s only used on that tab from the big query and update all the element on the tab to be up to date with the recent data
my problem is:
I fetched the data and updated all the elements successfully with the updated data
but when I hit the refresh button that’s on the browser to refresh the page the recent data that I pulled from the big query has gone and somehow I returned to the previous status before the data reload
again my main problem is when I refresh the data from the big query they overwrite it with my existing one successfully and I trigger all elements to use the recent data but the problem comes when I click on f5 to refresh the page itself, it behaves like I didn’t refresh the data from the big query

this is one of my simple tabs:

from components.utilities import (
    dmc,
    dcc,
    html,
    dash_table,
    callback,
    Output,
    Input,
    State,
    dbc,
    pd,
    plt,
    mcolors,
    DashIconify,
    callback_context,
    PreventUpdate,
    clientside_callback,
    MULTI_SELECT_STYLE,
    LOAD_DATA_BUTTON_STYLE_2,
    is_trigger_exist,
    generate_charts_div,
    generate_iframes,
    Toggle,
)

print("MONITORING".center(150, "="))

from components.eq_charts import *
from data.fetch_data import fetch_and_save_all_data
from data.common_dataframes import Data

toggle = Toggle()


class GenerateMonitoringData(Data):
    def __init__(self):
        super().__init__()


data_generator = GenerateMonitoringData()

data = data_generator.df_alpha_recent_backtest_log.sort_values(by="End_Time")
opt_ids = list(map(str, data.Optimization_ID.unique().tolist()))


def load_all_data_refresh():
    print("load_all_data_refresh".center(100, "#"))
    fetch_and_save_all_data(data_to_load=["AlphaRecentBacktestLog"])
    global data_generator
    data_generator = GenerateMonitoringData()
    refresh_processor()

    data = data_generator.df_alpha_recent_backtest_log.sort_values(by="End_Time")
    opt_ids = list(map(str, data.Optimization_ID.unique().tolist()))
    value = opt_ids[0] if opt_ids else None
    children = [
        dmc.Group(
            [
                dmc.Radio(label=i, value=i, color="gray", persistence=True)
                for i in opt_ids
            ],
            my=10,
        )
    ]
    return children, value


layout = html.Div(
    [
        dmc.Space(h=20),
        dcc.Store(id="hidden-loader-monitoring"),
        dbc.Row(
            [
                dbc.Col(
                    dmc.RadioGroup(
                        children=[
                            dmc.Group(
                                [
                                    dmc.Radio(label=i, value=i)
                                    for i in opt_ids
                                ],
                                my=10,
                            )
                        ],
                        value=opt_ids[0] if opt_ids else None,
                        id="optimization-id-select",
                        label="Select an Optimization ID",
                        size="sm",
                        mb=10,
                        # persistence=True,
                    ),
                    width=4,
                ),
                dbc.Col(
                    dmc.Group(
                        [
                            dmc.ActionIcon(
                                DashIconify(
                                    icon="mdi:database-sync",
                                    height=40,
                                    width=35,
                                ),
                                color="gray",
                                size="xl",
                                variant="transparent",
                                id="loading-button",
                                style=LOAD_DATA_BUTTON_STYLE_2,
                            ),
                            dmc.LoadingOverlay(
                                loaderProps={
                                    "type": "oval",
                                    "color": "red",
                                    "size": "xl",
                                },
                                overlayProps={"radius": "xl", "blur": 2},
                                visible=False,
                                id="loading-overlay",
                                style={"position": "absolute", "zIndex": 2000},
                            ),
                        ],
                        className="d-flex justify-content-start",
                    )
                ),
            ],
        ),
        dmc.Space(h=10),
        html.Div(generate_iframes((1, 1), 12, "gantt-iframe", height=1200)),
    ]
)


@callback(
    Output("loading-overlay", "visible", allow_duplicate=True),
    Input("loading-button", "n_clicks"),
    prevent_initial_call=True,
)
def display_loader(loading_button):
    ctx = callback_context
    trigger = ctx.triggered[0]["prop_id"].split(".")[0]

    if trigger == "loading-button":
        return True
    else:
        raise PreventUpdate


@callback(
    [
        Output("optimization-id-select", "children"),
        Output("optimization-id-select", "value"),
    ],
    [Input("loading-button", "n_clicks")],
    prevent_initial_call=True,
)
def refresh_data(loading_clickes):
    print("refresh_data".center(100, "#"))
    ctx = callback_context
    if not ctx.triggered:
        raise PreventUpdate

    trigger = ctx.triggered[0]["prop_id"].split(".")[0]
    if trigger == "loading-button":
        toggle.on_off = True
        return load_all_data_refresh()
    else:
        raise PreventUpdate


@callback(
    Output("loading-overlay", "visible", allow_duplicate=True),
    Input("hidden-loader-monitoring", "data"),
    prevent_initial_call=True,
)
def hidden_loader_champion(hidden):
    if toggle.on_off:
        toggle.on_off = False
        ctx = callback_context

        if is_trigger_exist(ctx, "hidden-loader-monitoring"):
            print("is_trigger_exist")
            return False
        else:
            print("Erorr: Champ Hidden Loader Not Found")
            raise PreventUpdate


@callback(
    Output("gantt-iframe-1", "srcDoc"),
    Output("hidden-loader-monitoring", "data"),
    Input("optimization-id-select", "value"),
)
def update_gantt_chart(optimization_ids):
    print("update_gantt_chart")
    print(data_generator.df_alpha_recent_backtest_log.sort_values('Optimization_ID'))
    series = create_gantt_series(optimization_ids)
    if not series:
        print("No data found")
        raise PreventUpdate
    return generate_gantt_chart(series, "Start & End Date By Machine IDs"), True

what I already tried is:

  • I ensured the data was correctly loaded
  • all elements are triggered when the refresh from the big query finished
  • I tried to use persistence=True, and storage_type=“local” on the radio button

NOTE:
when I printed the data after the reload data finished and even after hitting f5 to refresh the page itself the data was updated only the radio button didn’t get updated
actually, when I stopped the app and rerun it the app started with the updated data, and the radio button was updated too

keep in mind:

  • I need a solution that works not only locally but on the server too because I’m hosting the app on the AWS server
  • I need a proper solution that could work for all pages and tabs

I’m very excited to discuss it and learn new solutions from expert people
thanks

Hi @SayedB7r

What I understand from your app :

  • you fetch your data from somwhere at initialization time (i.e. when the app starts, not when a new user enter the page).
  • the users can refresh the data by clicking on “loading-button”.

You say that if you reload the page, your data comes back to the first state.
But I imagine that if you click again on the loading-button, then it works again. Correct ?

It think it is because you have prevent_initial_call=True on refresh_data callback. If you set it to False, it will trigger this callback every time that a user load the page / refresh the page.

What’s happening is that Dash saved an initial layout for your app. Your initial layout is based on some data. Every time that people reload the page, Dash will give you back this layout.
Note that upating data and data_generator in load_all_data_refreshwill NOT update this layout that Dash initially created.

Hope it helps ?