The dcc_store
component is used to store JSON data in the browser.
Find a few usage examples below.
using Dash
# This stylesheet makes the buttons and table pretty.
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
global app = dash(external_stylesheets=external_stylesheets)
app.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_table([
html_thead([
html_tr(html_th("Click to store in:", colSpan="3")),
html_tr([
html_th(html_button("memory", id="memory-button")),
html_th(html_button("localStorage", id="local-button")),
html_th(html_button("sessionStorage", id="session-button"))
]),
html_tr([
html_th("Memory clicks"),
html_th("Local clicks"),
html_th("Session clicks")
])
]),
html_tbody([
html_tr([
html_td(0, id="memory-clicks"),
html_td(0, id="local-clicks"),
html_td(0, id="session-clicks")
])
])
])
])
# Create two callback for every store.
for store in ("memory", "local", "session")
# add a click to the appropriate store.
callback!(app, Output(store, "data"),
Input(string(store, "-button"), "n_clicks"),
State(store, "data")) do n_clicks, data
if n_clicks isa Nothing
# prevent the None callbacks is important with the store component.
# you don't want to update the store for nothing.
throw(PreventUpdate())
end
# Give a default data dict with 0 clicks if there's no data.
if typeof(data) == Nothing
data = (clicks = 0,)
else
data = isempty(data) ? (clicks = 0,) : data
end
data = (;data...,clicks = data[Symbol("clicks")]+1)
return data
end
# # output the stored clicks in the table cell.
callback!(app, Output(string(store, "-clicks"), "children"),
# Since we use the data prop in an output,
# we cannot get the initial data on load with the data prop.
# To counter this, you can use the modified_timestamp
# as Input and the data as State.
# This limitation is due to the initial None callbacks
# <a href="https://github.com/plotly/dash-renderer/pull/81">https://github.com/plotly/dash-renderer/pull/81</a>
Input(store, "modified_timestamp"),
State(store, "data")) do ts, data
if ts isa Nothing
throw(PreventUpdate())
end
data = (typeof(data) == Nothing) ? NamedTuple() : data
if haskey(data, Symbol("clicks"))
return data[Symbol("clicks")]
else
return 0
end
end
end
run_server(app, "0.0.0.0", debug=true)
Click to store in: | ||
---|---|---|
Memory clicks | Local clicks | Session clicks |
using Dash
using CSV, DataFrames
app = dash()
df = CSV.read(download("https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv"), DataFrame)
countries = Set(df[!,"country"])
app.layout = html_div([
dcc_store(id="memory-output"),
dcc_dropdown(id="memory-countries", options=[
Dict("value" => x, "label" => x) for x in countries
], multi=true, value=["Canada", "United States"]),
dcc_dropdown(id="memory-field", options=[
Dict("value" => "lifeExp", "label" => "Life expectancy"),
Dict("value"=> "gdpPercap", "label"=> "GDP per capita"),
], value="lifeExp"),
html_div([
dcc_graph(id="memory-graph"),
dash_datatable(
id="memory-table",
columns=[Dict("name" =>i, "id" => i) for i in names(df)]
),
])
])
callback!(app,
Output("memory-output", "data"),
Input("memory-countries", "value")) do countries_selected
if countries_selected isa Nothing
# Return all the rows on initial load/no country selected.
return [Dict(pairs(NamedTuple(eachrow(df)[j]))) for j in 1:nrow(df)]
end
return [Dict(pairs(NamedTuple(eachrow(df)[j]))) for j in 1:2]
# filtered = df.query("country in @countries_selected")
# return filtered.to_dict("records")
end
run_server(app, "0.0.0.0", debug=true)
@app.callback(Output("memory-table", "data"),
Input("memory-output", "data"))
def on_data_set_table(data)=>
if data is None=>
raise PreventUpdate
return data
callback(app, Output("memory-graph", "figure"),
Input("memory-output", "data"),
Input("memory-field", "value")) do data, field)
if data isa Nothing
throw(PreventUpdate())
end
aggregation = DefaultDict("lambda" => DefaultDict(Array))
for row in data
a = aggregation[row["country"]]
a["name"] = row["country"]
a["mode"] = "lines+markers"
a["x"].append(row[field])
a["y"].append(row["year"])
end
return Dict(
"data"=> [x for x in aggregation.values()]
)
end
if __name__ == "__main__"=>
app.run_server(debug=True, threaded=True, port=10450)
modified_timestamp
is read only.If you use the data
prop as an output, you cannot get the
initial data on load with the data
prop. To counter this,
you can use the modified_timestamp
as Input
and the data
as State
.
Our recommended IDE for writing Dash apps is Dash Enterprise’s
Data Science Workspaces,
which has typeahead support for Dash Component Properties.
Find out if your company is using
Dash Enterprise.
id
(String; required):
The ID of this component, used to identify dash components in
callbacks. The ID needs to be unique across all of the components in
an app.
storage_type
(a value equal to: ‘local’, ‘session’ or ‘memory’; default 'memory'
):
The type of the web storage. memory: only kept in memory, reset on
page refresh. local: window.localStorage, data is kept after the
browser quit. session: window.sessionStorage, data is cleared once the
browser quit.
data
(Dict | Array | Real | String | Bool; optional):
The stored data for the id.
clear_data
(Bool; default false
):
Set to true to remove the data contained in data_key
.
modified_timestamp
(Real; default -1
):
The last time the storage was modified.