Share variable between pages

Hello All !,

Question from a real beginner…
I’m trying to use dcc.Store() to share data frame between two pages,
code for app.py:

app.layout = dbc.Container([
    html.Div(
        dcc.Store(id='data-store', data={})),
    dbc.Row([
        dbc.Col(
            html.Div("Gdp -- Life exp Analysis",
            style={'fontsize':100, 'textAlign': 'center', 'font-weight': 'bold'}))]),
    html.Hr(),
    
    dbc.Row([
        dbc.Col([
            sidebar],
            xs=4,
            sm=4,
            md=2,
            lg=2,
            xxl=2),
        dbc.Col([
            dash.page_container],
            xs=8,
            sm=8,
            md=10,
            lg=10,
            xxl=10)])
    ], 
    fluid=True)

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

Code first app, build the store component. This part works fine,

layout = html.Div([
    html.H3('By continent, gdp -- life exp'),
    html.Div(
        dcc.Store(id='data-store',storage_type='local')
        ),
    html.Div([
        dbc.Row([
            dbc.Col([
                html.Br(),
                html.H4('Table, from selected continent'),
                html.Br(),
                html.Br(),
                dcc.Dropdown(id='dropdown', options=df['continent'].unique(), value='Europe'),
                dash_table.DataTable(id='data-table', 
                                     page_size=10,
                                     fixed_columns={'headers': True, 'data': 1})
                ]),
            dbc.Col([
                html.Br(),
                html.H4('Graph, from selected continent'),
                dcc.Graph(id='graph', figure={}),
            ]),
        ]),
    ]),
    ])


@callback(
    Output(component_id='data-store', component_property='data'),
    Input(component_id='dropdown', component_property='value'))
def fn_store(continent):
    if not continent:
        return df.to_dict('records')
    df_continent = df[df['continent'] == continent]
    return df_continent.to_dict(orient='records')



@callback(
    Output(component_id='data-table', component_property='data'),
    Input(component_id='dropdown', component_property='value'))
def fn_table(continent):
    df_continent = df[df['continent'] == continent]
    return df_continent.to_dict(orient='records')



@callback(
    Output(component_id='graph', component_property='figure'),
    Input(component_id='dropdown', component_property='value'))
def fn_graph(continent):
    df_from_selected_continent = df[df['continent'] == continent]
    fig = px.scatter(df_from_selected_continent,
                     x='gdpPercap',
                     y='lifeExp',
                     size='pop',
                     color='country',
                     hover_name='continent')
    return fig

Code that does not return DataTable as I expect

layout = dbc.Container([
    dbc.Row([
        html.Div([
            html.H1('full table'),
            html.Hr()]),
        html.Div([
            dcc.Store(id='data-store'),
            dash_table.DataTable(id='full-table', data=[], page_size=10)]),
        ]),
    ])
@callback(
    Output('full-table', 'data'),
    Input('data-store', 'data'))
def fn_full(data):
    return data

There is no error message, but I do not get the table I expect,
Despite searches on the web, I do not see any useful information…

Could you help on this ?

Many thanks !

Hi @Olivier_fr

Here is an example that’s very similar. Note that if the dcc.Store is in app.py then it’s available to every page in your multi-page app.

Your code seems to have this in the layout twice:

dcc.Store(id='data-store')

I think it only needs to go in the layout once (probably best in app.py), and duplicating it may cause a duplicate ID error (which I’d expect to be visible in the browser console though, so if you’re not seeing any errors there I may have the wrong idea)

Many thanks for replies,

From comments, I made some changes:


dash.register_page(__name__, 
                   path='/',
                   location="sidebar")

layout = dbc.Container([
    dbc.Row([
        html.Div([
            html.H1('full table'),
            html.Hr()]),
        html.Div(dash_table.DataTable(id='full-table', data=[], page_size=10))]),
    ])
            
@callback(
    Output('full-table', 'data'),
    Input('data-store', 'data'))
def fn_full(data):
    return data

Get error message,

Invalid argument `data` passed into DataTable with ID "full-table".
Expected an array.
Was supplied type `object`.
Value provided: {}

Definitely something I don’t understand correctly…

Thank you for your help on this

It looks like you might have stored a dictionary rather than a list in data-store. That’s not what I’d expect your previous code to do though (df.to_dict(orient=‘records’)). Is there some other code that outputs to data-store?

Yes, indeed dcc.store outputs a dictionary, so for that dictionary to be imputed in dash_table.DataTable() it requires to be converted in array before ?
Arr = pd.DataFrame(data.values())

Am I right ? :saluting_face:

Thank you for your help!

You can store either an array or a list in a dcc.Store().

I’m thinking that if what you Output to a dcc.Store is the result of a df.to_dict(orient=‘records’) then that’s a list, and should be in the right (list) format to use as data in a DataTable when you retrieve it from the Store.

I don’t understand why it’s not in your case

Hello All !,

I would need some help with the following,

I just want to understand how to share variable between pages using dcc.Store().
Data frame is stored in dcc.Store() component, then used to display table. Got error message saying “children” is not a correct property,

Can you give me ideas so I understand what is wrong here ?

Many thanks for help!

Code app.py page

import dash
import pandas as pd
from dash import Dash, dcc, html, Input, Output, callback
from dash import dcc
from dash.dependencies import Input, Output
from dash import dash_table
import dash_bootstrap_components as dbc

app = dash.Dash(__name__, 
                use_pages=True,
                external_stylesheets=[dbc.themes.SPACELAB])

sidebar = dbc.Nav(
    [dbc.NavLink(
        
        [html.Div(page['name'], className='ms-2')],
        
        href=page['path'],
        
        active='exact') for page in dash.page_registry.values()],
    
    vertical=True,
    pills=True,
    className='bg-light')




app.layout = dbc.Container([
    html.Div(
        dcc.Store(id='data-store', data={})),
    dbc.Row([
        dbc.Col(
            html.Div("Gdp -- Life exp Analysis",
            style={'fontsize':100, 'textAlign': 'center', 'font-weight': 'bold'}))]),
    html.Hr(),
    
    dbc.Row([
        dbc.Col([
            sidebar],
            xs=4,
            sm=4,
            md=2,
            lg=2,
            xxl=2),
        dbc.Col([
            dash.page_container],
            xs=8,
            sm=8,
            md=10,
            lg=10,
            xxl=10)])
    ], 
    fluid=True)

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

Code Analytics.py page

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')

dash.register_page(__name__,
                   path='/analytics-dashboard',
                   title='Our Analytics Dashboard',
                   name='Our Analytics Dashboard',
                   location="sidebar")

layout = dbc.Row([
    html.H2('By continent, gdp -- life exp'),
    html.Hr(),
    html.H3('Full table'),
    
    dcc.Store(id='data-store',storage_type='local'),
    dash_table.DataTable(data=df.to_dict('records'),
                             id='full-table',
                             page_size=10,
                             fixed_columns={'headers': True, 'data': 1}
                             )
    ])

@callback(
    Output(component_id='data-store', component_property='data'),
    Input(component_id='full-table', component_property='data'))
def fn_display_full_table(data):
    return data

Error message

Property "children" was used with component ID:
  "full-table"
in one of the Output items of a callback.
This ID is assigned to a dash_table.DataTable component
in the layout, which does not support this property.
This ID was used in the callback(s) for Output(s):
  full-table.children```

I made some changes from above code,

``
df = pd.read_csv(‘https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv’)

dash.register_page(name,
path=‘/analytics-dashboard’,
title=‘Our Analytics Dashboard’,
name=‘Our Analytics Dashboard’,
location=“sidebar”)

layout = html.Div([
dcc.Store(id=‘store’, data=df.to_dict(‘records’)),
dash_table.DataTable(data=, id=‘table’, page_size=10)])

@callback(
Output(‘table’, ‘data’),
Input(‘store’, ‘data’))
def fn_table(data):
return data

This works, hope this helps :wink: