Cannot get Store to work with my tabs

Hi,

I’m trying to store the content of a tab, so it is not loaded as default every time I switch tab, using dcc.store.

My code looks like the following;

index.py

import dash_html_components as html
import dash_core_components as dcc

from dash.dependencies import Input, Output

from app import app
from apps import data, terrain

tabs_styles = {
    'height': '44px'
}
tab_style = {
    'borderBottom': '1px solid #d6d6d6',
    'padding': '6px',
    'fontSize': '24px'
}

tab_selected_style = {
    'borderTop': '1px solid #d6d6d6',
    'borderBottom': '1px solid #d6d6d6',
    'backgroundColor': '#bababa',
    'color': 'white',
    'padding': '6px',
    'fontSize': '24px'
}

app.layout = html.Div([
    dcc.Tabs(id="tabs-styled-with-inline", value='tab-data', children=[
        dcc.Tab(label='Data', value='tab-data', style=tab_style, selected_style=tab_selected_style),
        dcc.Tab(label='Ter', value='tab-ter, style=tab_style, selected_style=tab_selected_style),
    ], style=tabs_styles),
    html.Div(id='tabs-content-inline')
])

@app.callback(Output('tabs-content-inline', 'children'),
              [Input('tabs-styled-with-inline', 'value')])
def render_content(tab):
    if tab == 'tab-data':
        return data.layout
    elif tab == 'tab-ter':
       return ter.layout


if __name__ == '__main__':
    app.run_server(debug=True)

data.py

layout = html.Div([
    # The memory store reverts to the default on every page refresh
    dcc.Store(id='memory'),
    # The local store will take the initial data
    # only the first time the page is loaded
    # and keep it until it is cleared.
    dcc.Store(id='local', storage_type='local'),
    # Same as the local store but will lose the data
    # when the browser/tab closes.
    dcc.Store(id='session', storage_type='session'),
    html.Div(children=[
        html.Div(
            dcc.Upload(
                id='upload-data',
                children=html.Div([
                    'Drag and Drop or ',
                    html.A('Select Files')
                ]),
                style={
                    'width': '100%',
                    'height': '60px',
                    'lineHeight': '60px',
                    'borderWidth': '1px',
                    'borderStyle': 'dashed',
                    'borderRadius': '5px',
                    'textAlign': 'center',
                    'margin': '10px'
                },
                # Allow multiple files to be uploaded
                multiple=True,
            ), className='two columns'
        ),
        html.Div(
            dash_table.DataTable(
                id='file-table',
                columns=[{"name": p, "id": p} for p in params],
                style_cell={
                    'textAlign': 'left',
                    'width': '15px'
                },
                style_table={
                    'maxHeight': '300px',
                    'overflowY': 'scroll',
                    'margin': '5px',
                },
                row_selectable='multi',
            ), className='ten columns'
        )
    ], className='row'
    ),
    html.Div(id='hidden-div', style={'display': 'none'})
])

# output the stored clicks in the table cell.
@app.callback(Output('file-table', 'data'),
              [Input('session', 'modified_timestamp')],
              [State('session', 'data')])
def on_data(ts, data):
    if ts is None:
        raise PreventUpdate

    data = data or {}
    print(data.get('table_content', ''))
    return data.get('table_content', '')


@app.callback(Output('session', 'data'),
              [Input('upload-data', 'contents')],
              [State('upload-data', 'filename'),
               State('upload-data', 'last_modified'),
               State('session', 'data')])
def update_output(list_of_contents, list_of_names, list_of_dates, data):
    global df
    df_tmp = pd.DataFrame(columns=feature_file_structure_v8)

    if list_of_contents is not None:
        for c, n, d in zip(list_of_contents, list_of_names, list_of_dates):
            parse_contents(c, n, d)
            df_tmp = pd.concat([df, df_tmp], axis=0, ignore_index=True)

    df = df_tmp.sort_values(by=['epochTime']).reset_index(drop=True)

    table_data = [{'Filename': f} for f in df.fileName.unique()]
    data = data or {'table_content': ''}
    data['table_content'] = table_data

    return data

I want to save the values from the dash_table, so when I get back to the this tab it will remember it all.
What I see so far when, files are uploaded and the filenames is stored in the dcc.Store where I use session. It will on reload or by clicking by clicking on the tab where I’m already at (data.py), go to “on_data” function, but the dcc.Store is empty?
Furthermore, by clicking on tab “ter” and then back to “data”, it will not trigger “on_load”.

Can someone help me?

The code is based on the Store | Dash for Python Documentation | Plotly “store click example”

Also, I do get an error “Unexpected token u in JSON at position 0”

This is an interesting idea…

An simple fix is to put the content of each tab in the layout rather than rendering the content anew each time a new tab is selected. This way, the other tab’s content is never lost, and you don’t need a function to switch the content. This is only a problem if there is a lot of memory overhead involved for one of the tabs, e.g. 30 charts and a 100,000 row table as a dict in a hidden div.

Could you give an example of this?
Updating with new data is still important for me.

My problem is,
I want to use one tab to upload files with the data, and from that also choose which files I want to work with. The chosen files should then be used in other tabs with graph etc.

So how can I update data dynamically if I put the content in the layout?