I did but it is not returning in the webapp but it is printing in console.
Well, you need to review the boostrap Toast first.
See that in the example uses Output(âauto-toastâ, âis_openâ) to change from False to True to show the component.
First try just to do the Toast work alone (out of your program) and then add to it.
Hope it helps.
Hey @matsujju
Thereâs some bits missing from your code so I couldnât run it exactly, but I made a minimal working example of toasts displaying results to the user.
import json
from random import randint
from uuid import uuid4
import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import ALL, Input, Output, State
app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Container(
[
# store will save all messages to display to the user
# this is client-side so user specific
dcc.Store(id="message-store"),
html.H1("Toast demo"),
html.P(
"Click on generate, you'll get a random number pop up in a toast"
),
dbc.Button("Generate number", id="button"),
# create a container for the toasts and position to the top right
html.Div(
id="toast-container",
style={"position": "fixed", "top": 10, "right": 10, "width": 350},
),
],
className="p-5",
)
@app.callback(
Output("message-store", "data"),
[
Input("button", "n_clicks"),
Input({"type": "toast", "id": ALL}, "n_dismiss"),
],
[State("message-store", "data")],
)
def manage_store(n, dismissed_toast, store):
"""
This callback manages the message store.
If the "generate" button is clicked we add an item to the store
If one of the toasts is dismissed we remove the corresponding item from the
store.
To figure out which of these happened, we use callback context.
"""
ctx = dash.callback_context
triggered = ctx.triggered[0]["prop_id"]
if n and triggered == "button.n_clicks":
# button has been clicked, return a new list of messages
# generate a random id using uuid.uuid4
return [*store, {"number": randint(0, 100), "id": str(uuid4())}]
elif triggered.endswith(".n_dismiss"):
id_, _ = triggered.split(".")
# recover id of dismissed toast
id_ = json.loads(id_)["id"]
# filter it from the store
return [item for item in store if item["id"] != id_]
return []
def make_toast(message, id_):
"""
Helper function for making a toast. dict id for use in pattern matching
callbacks.
"""
return dbc.Toast(
message,
id={"type": "toast", "id": id_},
key=id_,
header="Positioned toast",
is_open=True,
dismissable=True,
icon="danger",
)
@app.callback(
Output("toast-container", "children"), Input("message-store", "data")
)
def display_toasts(store):
"""
When the store updates, update the displayed toasts.
"""
return [
make_toast(f"A random number: {item['number']}", item["id"])
for item in store
]
if __name__ == "__main__":
app.run_server(debug=True)
Hereâs how it works:
- Messages that should be shown to the user are saved in a
dcc.Store
alongside an id so you can keep track of which message is which. - Anytime the store is updated, a callback keeps the toasts up to date.
- A second pattern-matching callback keeps the store up to date, watching for new messages being created, and also watching for any of the toasts to be dismissed. If any of them are dismissed it will remove them from the store.
Hope you will be able to apply similar logic to your app!
Thanks for your example but can you tell me what is the issue in my code and why I am not able to output the result in frontend side (webapp though the results are printing in console on printing).
Moreover, I havenât used dash.callback_context
earlier and count be beginner in Dash, so I want to keep things simple thatâs why I used my Toast inside layout and is it necessary to use Store
with Toast
component?
I donât mind using another component for output if Toast is not working out. I just to show the results to user in clear, elegant way.
I tried your way though Toast is now showing in dashboard but not the result not even empty list.
I am attaching the screenshot.
Are you passing []
as the children of the toast? When you pass children to a Dash component, if it finds a list it assumes itâs a list of children to display. An empty list of children is the same as no children, i.e. no content and hence an empty toast. What happens if you return something like str(results)
from the callback? In that case you might see a []
displayed.
what is the issue in my code and why I am not able to output the result in frontend side
I wasnât able to easily figure that out because as mentioned I couldnât run your code, but I think itâs probably a combination of:
- Not setting
is_open=True
on the Toasts, which means they are hidden - Setting the
children
of the toast to equal[]
which is equivalent to having no content.
I have done both but still results are not shown in webapp but Toast component is now showing.
Yes it is printing empty list in console.
It will be possible that you was not able to reproduce it as I just gave layout and callbacks but I have many custom functions for preprocessing of data and some pickle files loading which I might not able to provide.
But are you actually returning anything? Printing will only display stuff in the console, you need to return something from the callback. If there is no explicit return statement then the callback will return None
and the toast will be empty.
As far as I can tell in this example you arenât returning anything in the callback, youâre just printing:
@app.callback(
Output("output-state", "children"),
[Input("submit-button", "n_clicks")],
[
State("input_text", "value"),
State("slider", "value"),
State("drop-down", "value"),
State("slider-2", "value"),
],
# prevent_initial_call=True,
)
def label_prediction(num_clicks, text, threshold_value, preprocess_func, label_value):
if text is None:
raise PreventUpdate
if num_clicks > 0:
params = ["remove_digits", "remove_stopwords", "text_lemmatization"]
dict_params = [param in preprocess_func for param in params]
preprocess_text = preprocess(text, *dict_params)
transformed_text = tfidf.fit_transform([preprocess_text])
prediction = classifier.predict_proba(transformed_text)
print(f"Predicted labels:{get_tags(prediction[0],threshold_value,label_value)}")
Oh noâŚyou misunderstood itâŚI am returning that was just to show that I used print also inside the function along with return.
def label_prediction(num_clicks, text, threshold_value, preprocess_func, label_value):
if text is None or num_clicks is None:
return dash.no_update
else:
params = ["remove_digits", "remove_stopwords", "text_lemmatization"]
dict_params = [param in preprocess_func for param in params]
preprocess_text = preprocess(text, *dict_params)
transformed_text = tfidf.fit_transform([preprocess_text])
prediction = classifier.predict_proba(transformed_text)
# print("This is the result to show")
result = get_tags(prediction[0], threshold_value, label_value)
print(str(result))
return result
Thanks for your example but can you tell me what is the issue in my code and why I am not able to output the result in frontend side (webapp though the results are printing in console on printing).