Hello!
I am leaning how chained callbacks work in dash and stalled a bit, can someone more experienced have a look at the code below and show where I am doing it wrong?
The main idea is to use output callback that uses long_lasting_query()
as an input to another callbacks, but it looks like no callbacks were called at all. I am 100% sure that I am missed something very simple, but couldn’t spot the issue, so please help.
Self sufficent code below, I am using the last available release if Dash & Plotly.
import argparse
import dash_bootstrap_components as dbc
import pandas as pd
from dash import Dash, Input, Output, State, dcc, html
from dash.dash_table import DataTable
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Dash example",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"-a",
"--addr",
type=str,
metavar="arg",
required=True,
help="address to bind to (ip:port)",
)
parser.add_argument("--debug", action="store_true", help="run in debug mode")
args = parser.parse_args()
return args
def long_lasting_query() -> pd.DataFrame:
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv"
)
return df
columns = ["country", "continent", "year", "lifeExp", "pop", "gdpPercap"]
app = Dash(
external_stylesheets=[dbc.themes.BOOTSTRAP], suppress_callback_exceptions=True
)
app.layout = dbc.Container(
[
html.P(
"Year: ",
style={"display": "inline-block", "margin-right": "8px"},
),
dcc.Input(id="year", type="number", min=0),
html.Button("Submit", id="submit-val", n_clicks=0),
DataTable(
columns=[{"name": c, "id": c} for c in columns],
id="tbl",
page_size=20,
sort_action="native",
style_header={
"textAlign": "center",
},
),
]
)
@app.callback(
Output("db_data", "value"),
Input("submit-val", "n_clicks"),
State("year", "value"),
prevent_initial_call=True,
)
def load_data(n_clicks, value):
df = long_lasting_query()
df = df[df["year"] == value]
if df.empty:
return "{}"
return df.to_json(orient="split")
@app.callback(
Output("tbl", "data"),
Input("db_data", "value"),
)
def update_table(value):
df = pd.read_json(value, orient="split")
if df.empty:
return "{}"
return df.to_dict("records")
def main() -> None:
args = parse_args()
host, port = args.addr.split(":")
app.run(host=host, port=port, debug=args.debug)
if __name__ == "__main__":
main()