Values of Dcc.upload is not retained when I switch between the tabs

I am using multi tab layout in my dashboard… in the first tab, i am using dcc.upload to upload a file which will be generated to dash table. But if I switch between the tabs and come to first tab, the table and file got refreshed. I want the data to be retrieved even i switch between the tabs. Can anyone help to solve this problem. I am copying the code below.

#!/usr/bin/env python
# coding: utf-8

# In[3]:


# Importing Libraries

# (version 4.7.0 or higher) # higher level graphing library
import plotly.express as px
import plotly.graph_objects as go 
import dash
import dash_bootstrap_components as dbc
from datetime import datetime, timedelta
from dash import Dash, dash_table, html
from sklearn.metrics import mean_squared_error, mean_absolute_error
import numpy as np
import io
import time
from io import StringIO
import base64
from io import BytesIO
from collections import OrderedDict
import copy
from datetime import date
from dash.exceptions import PreventUpdate
# In[4]:
factors = pd.read_csv('factor_generators.csv')
agent_options = [{'label': i, 'value': i} for i in factors['Agent'].unique()]
# Instantiating the dash
app = Dash(__name__, external_stylesheets=[
           dbc.themes.BOOTSTRAP], suppress_callback_exceptions=True)
app.config.suppress_callback_exceptions = True
model = None
start_simulation = False
steps = 0
play = True
main_tab = "simulation_tabs"
Instantiation = False
site_data = pd.DataFrame()
data = pd.read_csv("clean_data.csv", index_col=[0, 1])
selected_site_details = []
added_sites = []
# real_data = pd.read_excel("real_data.xlsx")
model_df = None
# Selected sites will be stored in this list
selected_values = list()
data_store = {}
model_start_time = time.time()
time_interval = 1000
uploaded_data = pd.DataFrame()
protocol_data = None
factors_selected = []
source_nodes = []
target_nodes = []
steps = 0
# Plot variables
week = str(steps)
sd = datetime.now().date()
cd = sd + timedelta(days=steps)
ns = 0
acs = 0
ide = 0
cm = 0
cmr = 0
dc = 0
Sankey_fig = go.Figure()
Pie_fig = go.Figure()
Geo_fig = px.choropleth(scope="usa")
Line_fig = go.Figure()
Bar_fig = go.Figure()
validation_fig = go.Figure()
aed = 0
sed = 0
dd = 0
actual_complexity =0
baseline_complexity = 45
study_complexity = 0
competition_score = 0
sf=0
drp=0
Retrieve_in_intervention = True
# Creating variable for retrieving selected sites
Retrieve = False
site_count_track = []
# for the navigation between tabs.
current_tab = 'tab_1'
current_tab_list = ['tab_1', 'tab-1']
navigate_to = ""
remaining_sites = []

# In[5]:

# Creating style for input value
input_value_style = {
    "height": "25px",
    "fontSize": 20
}

tab_style = {
    "background-color": "white",
    "box-shadow": "0 2px 4px rgba(0, 0, 0, 0.2)",
    "padding": "20px",
    "margin": "10px",
}


simulation_toast_content_style = {"font-size": "30px", "text-align": "center"}
simulation_toast_header_style = {
    "font-size": "20px", "color": "black", "background-color": "#E5F3FD"}

custom_styles = {
    "accordion-container": {
        "max-width": "100%",  # Adjust the width as per your requirement
        "margin": "0 auto",    # To center the accordion horizontally
    },
    "accordion-content": {
        "font-size": "14px",   # Adjust font size as needed
    },
}

# In[5]:


# Creating the layout
app.layout = html.Div(
    id="container",
    className="app_container",
    children=[
        # Number 2. Creation of a row for the input and content.
        dbc.Row([
            # Number 3. Creating a column for the inputs (like a side bar with small width)
            dbc.Col([
                # Number 4. Creating a card for the inputs
                dbc.Card(
                    id='input_card',
                    children=[
                        # Number 7. Creating an outer accordion for Agent Creation (Home tab)
                        dbc.Row([
                            dbc.Accordion([
                                dbc.AccordionItem([
                                    dcc.Tabs(
                                                    id="agent_tabs",
                                                    value="tab_1",
                                                    
                                                    # className = "input-tabs-container",style = {"margin-top" : "10px", "margin-bottom" : "10px"}
                                                    #display: flex !important,align-items: center,justify-content: center;
                                                    # style = {"height":"10%","background-color":"white", "width": "100%","margin-left" : "2px", "margin-right" : "2px", "margin-top" : "20px"}, 'borderTop': '5px solid black'
                                                    children=[
                                                        dcc.Tab(label="Protocol Creation", value="tab_1", style={'color': '#0066b2', 'background-color': '#D8D8D8'}, selected_style={
                                                                'color': '#F0F8FF', 'background-color': '#0066b2', 'borderTop': '5px solid #00BFFF'}),
                                                        dcc.Tab(label="Site Creation", value="tab_2",style={'color': '#0066b2', 'background-color': '#D8D8D8'}, selected_style={
                                                                'color': '#F0F8FF', 'background-color': '#0066b2', 'borderTop': '5px solid #00BFFF'}),
                                                        dcc.Tab(label="Patients Creation", value="tab_3", style={'color': '#0066b2', 'background-color': '#D8D8D8'}, selected_style={
                                                                'color': '#F0F8FF', 'background-color': '#0066b2', 'borderTop': '5px solid #00BFFF'}),
                                                        # dcc.Tab(label="Spatial Location", value="tab_4", style={'color': '#0066b2', 'background-color': '#D8D8D8'}, selected_style={
                                                        #         'color': '#F0F8FF', 'background-color': '#0066b2', 'borderTop': '5px solid #00BFFF'})
                                                    ], colors={"background": "#968f94"},
                                                    vertical=True,
                                                    style={'margin-left':'10px'}
                                                ),
                                                
                                    dbc.Row([dbc.Button("Start Simulation", id="simulation_button", color="primary", disabled=False,
                                                        style={"width": "100%", "align-text": "center", "font-size": "20px", "margin-left": "2px", "margin-right": "2px",
                                                               "justify-content": "center"}), ], justify='center'),
                                ],
                                    title="Agents Creation",
                                    style={'background-color':'#F0F8FF'}
                                ),
                            ],
                                id="outer_accordion",
                                className="custom-accordion",
                                # Apply custom styles
                                style=custom_styles["accordion-container"],
                                # start_collapsed=True
                            ),
                        ]),
                        # Number 17. Creating Tabs for Simulation, validation, Report
                        dbc.Row([
                            # dcc.Store(id="demo_store", data={}),
                            dcc.Tabs(
                                id="simulation_tabs",
                                 # normal - 'color': '#F0F8FF', 'background-color': '#0066b2'
                                #active - 'color': '#0066b2', 'background-color': '#F0F8FF',
                                # value = 'tab_8',
                                # className = "input-tabs-container",style={'color':'white','background-color': '#1877F2'}
                                children=[
                                    dcc.Tab(label="Simulation", value="tab_8", style={'font-size': '20px', 'color': '#0066b2', 'background-color': '#D8D8D8'}, selected_style={
                                            'color': '#F0F8FF', 'background-color': '#0066b2', 'borderTop': '5px solid #00BFFF'}),
                                    dcc.Tab(label="Validation", value="tab_9", style={'font-size': '20px', 'color': '#0066b2', 'background-color': '#D8D8D8'}, selected_style={
                                            'color': '#F0F8FF', 'background-color': '#0066b2', 'borderTop': '5px solid #00BFFF'}),
                                    dcc.Tab(label="Reports", value="tab_10", style={'font-size': '20px','color': '#0066b2', 'background-color': '#D8D8D8'}, selected_style={
                                            'color': '#F0F8FF', 'background-color': '#0066b2', 'borderTop': '5px solid #00BFFF'})
                                ], colors={"background": "#968f94"},
                                style={'font-size': '20px', "width": "100%",
                                       "margin-left": "2px", "margin-right": "2px"},
                                vertical=True,
                            ),
                        ])

                    ], style={'height': '900px', "background-color": "#F0F8FF"})
            ], style={"background-color": "c"},width=2),
            # Number 5. Creating a column for contents of the page.(larger width)
            dbc.Col([
                html.Div(children=[dcc.Loading(id="loading-1", type="default", children=html.Div(
                    id="loading-output-1"),)], style={'margin-top': '20px'}),
                dcc.Store(id="demo_store", data={}),
                
                html.Div(id='content', style={
                         'height': '900px', "background-color": "#F0F8FF"}),
                html.Div(id='content_1', style={
                         'height': '900px', "background-color": "#F0F8FF", 'display': 'none'},
                         ),
                html.Div(id='content_2', style={
                         'height': '900px', "background-color": "#F0F8FF", 'display': 'none'},
                         ),
                html.Div(id='content_3', style={
                         'height': '900px', "background-color": "#F0F8FF", 'display': 'none'},
                         ),
                html.Div(
                    id = "content_4", style={'height': '900px', "background-color": "#F0F8FF", 'display': 'none'}
                ),
                html.Div(
                    id = "content_5", style={'height': '900px', "background-color": "#F0F8FF", 'display': 'none'}
                ),
                html.Div(
                    id = "content_6", style={'height': '900px', "background-color": "#F0F8FF", 'display': 'none'}
                ),
                html.Div(
                    id = "content_7", style={'height': '900px', "background-color": "#F0F8FF", 'display': 'none'}
                ),
                html.Div(
                    id = "content_8", style={'height': '900px', "background-color": "#F0F8FF", 'display': 'none'}
                ),
                html.Div(
                    id = "content_9", style={'height': '900px', "background-color": "#F0F8FF", 'display': 'none'}
                ),
                
            ], width=10),
        ])
    ], style={"background-color": "#F0F8FF", 'height': '98vh', 'display': 'flex'})
### 1. Protocol Creation Content Tab
protocol_content = html.Div([
    dbc.Card([
    # dcc.Store(id="demo_store", data={}),
    # Creating Primary inputs contents (row)
    dbc.CardHeader("Patient - PI - Site Inputs", style={"backgroundColor": "#0066b2",
                   "color": "white", "text-align": "center", "font-size": "20px", 'width': '100%'}),
    dbc.Row([
        dbc.Col(html.H5("Upload the Protocol Data"),style={'margin-top':'20px'}),
        dbc.Col(dcc.Upload(
                        id='upload_data',
                        children=html.Div([
                            'Drag and Drop or ',
                            html.A('Select Files')
                        ]),
                        style={
                            'width': '90%',
                            'height': '50px',
                            'lineHeight': '50px',
                            'borderWidth': '1px',
                            'borderStyle': 'dashed',
                            'borderRadius': '5px',
                            'textAlign': 'center',
                            'margin': '10px'
                        },
                        ),style={'margin-left':'-300px'}),
                    dbc.Col([dbc.Button("Upload", id="submit-button", color="primary",n_clicks=0,
                                        disabled=False, style={"width": "100px",'margin-top':'15px','margin-left':'-10px',
                                                               "align-text": "center", "font-size": "20px",
                                                               "justify-content": "center"}), ]),
                    
                    
                    html.Div(id="protocol_data", children=[]),]),
                    html.Hr(),
                    html.Div(id='datatable-container'),
                    dcc.Store(id='file-store', storage_type='memory'),
                    dcc.Store(id='datatable-store', storage_type='memory'),
                    
], style={"max-width": "100vw", "overflow-x": "hidden", 'height': '900px', 'border': 'none', "background-color": "#F0F8FF",
          "border": "0", "box-shadow": "none",'margin-top':'-15px'})
])
### 2. Site Creation Content Tab
site_content =html.Div([
    html.Div(id='cards-container')
])
### 3. Patient Creation Content Tab
patient_content=html.Div([
    html.P(' this is patient content tab')
])

### 4. Simulation Content
simulation_content=html.Div([
    html.P(' this is simulation content tab')
])
### 5. Validation Content
validation_content=html.Div([
    html.P(' this is validation content tab')
])
### 6. Reports COntent
reports_content=html.Div([
    html.P(' this is reports content tab')
])

# 1.  Creating callback to view different tabs
@app.callback(
    [Output('content', 'children'),
     Output('agent_tabs', 'value'),
     Output('simulation_tabs', 'value')],
    [Input('agent_tabs', 'value'),
     Input('simulation_tabs', 'value')]
)
def update_agent_tab_content(tab1,tab2):
    global current_tab, current_tab_list, navigate_to
    l = [tab1, tab2]
    change = set(l) - set(current_tab_list)
    if len(change) > 0:
        filtered_values = [value for value in change if value is not None]
        if filtered_values:
            current_tab = filtered_values[0]
        else:
            current_tab = 'tab_1'
    else:
        current_tab = "tab_1"
    current_tab_list = l

    # Navigation
    if navigate_to == "simulation_page":
        current_tab = "tab_8"
        navigate_to = ""
    # print(selected_tab,selected_sim_tab)
    if current_tab == 'tab_1': 
        current_tab_list = ['tab_1', 'tab-1']
        return (protocol_content,tab1,None)
    elif current_tab == 'tab_2':
        current_tab_list = ['tab_2', None]
        return (site_content,tab1,None)
    elif current_tab == 'tab_3':
        current_tab_list = ['tab_3', None]
        return (patient_content,tab1,None)
    elif current_tab == 'tab_8':
        current_tab_list = [None,'tab_8']
        return (simulation_content,None,tab2)
    elif current_tab == 'tab_9':
        current_tab_list = [None,'tab_9']
        return (validation_content,None,tab2)
    elif current_tab == 'tab_10':
        current_tab_list = [None,'tab_10']
        return (reports_content,None,tab2)
    else:
        # Default content or error handling
        return html.Div('Invalid tab selected')
   
### 2. Uploading CSV for protocol

@app.callback(Output('file-store', 'data'),
              Input('upload_data', 'contents'),
              State('upload_data', 'filename'),
              State('upload_data', 'last_modified'))
def store_real_data(contents, filename,modified_file):
    global uploaded_data
    if contents is None:
        raise PreventUpdate

    elif contents is not None:
        content_type, content_string = contents.split(',')

        # Decode and read the uploaded file content
        decoded_content = base64.b64decode(content_string)

        # Determine the file extension from the filename
        file_extension = filename.split('.')[-1].lower()

        # Check if the file extension is CSV
        if file_extension == 'csv':
            df = pd.read_csv(io.StringIO(decoded_content.decode('utf-8')))
        # Check if the file extension is Excel
        elif file_extension in ['xls', 'xlsx']:
            df = pd.read_excel(io.BytesIO(decoded_content))

        # Store the DataFrame or perform other operations
        uploaded_data = df
    
        return (html.Div([
            html.P(f'Uploaded Filename: {filename} with '
           f'Number of rows: {df.shape[0]} and '
           f'Number of columns: {df.shape[1]}')
        ]),)
   
    return (html.Div([
        html.A('Select File')
    ]),)

@app.callback([Output('datatable-store', 'data'),
               Output('content_1', 'children')],
              [Input('submit-button', 'n_clicks'),
               Input('file-store','data')],
              [State('upload_data', 'contents')])
def update_datatable(n_clicks, data,contents):
    if n_clicks > 0 and contents is not None:
        df = uploaded_data
        # df = pd.read_csv(pd.io.common.StringIO(contents))
        data = df.to_dict('records')
        print('new function')
        print(data)
        # Returning data to store, and rendering DataTable in both tabs
        return data, generate_datatable(data)

    return None, None

@app.callback(Output('datatable-container', 'children'),
              [Input('datatable-store', 'data')],
              prevent_initial_call=True)
def update_tab1(data):
    if data:
        return generate_datatable(data)
    return None

def generate_datatable(data):
    return dash_table.DataTable(
        id='datatable',
        columns=[{'name': col, 'id': col} for col in data[0].keys()],
        data=data,
        style_table={'overflowY': 'scroll', 'overflowX': 'scroll'},
        style_cell={'textAlign': 'left'},
        editable=True,
        filter_action="native",
        sort_action="native",
        sort_mode="multi",
        column_selectable="single",
        row_selectable="multi",
        row_deletable=True,
        selected_columns=[],
        selected_rows=[],
        page_action="native",
        page_current=0,
        page_size=50,
        persistence=True,
        persistence_type='memory',
    )

## dcc.Upload persistance
@app.callback(
    Output('uploaded-files', 'children'),
    [Input('upload_data', 'contents')],
    prevent_initial_call=True
)
def store_uploaded_files(uploaded_files):
    return uploaded_files

# Running the server
if __name__ == '__main__':
    app.run_server(debug=True, port=8080, dev_tools_hot_reload=False)

How do you store the uploaded data?

Just a comment: Scanning to your code I’ve seen you are using global variables.

Yes currently i am using a global variable to store the uploaded data…but it is coming in the dash table… i am facing problem with dcc.upload as the contents are reset to None if I navigate between tabs.

I understood your issue.

Please try stripping down your code to make it easier for users to help you debugging.

Yeah Sure…I’ll do it from now on
It would be helpful if I get a solution as this is a critical project