I have created tabbed layout for my Dash app:
import dash
import dash_table
import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbc
TAB_LAYOUT = html.Div([
dcc.Tabs(id="tabs-main", value='tab-intro', children=[
dcc.Tab(label='Introduction', value='tab-intro'),
dcc.Tab(label='Your Files', value='tab-files'),
dcc.Tab(label='Basic', value='tab-basic'),
...
app.layout = html.Div([
TAB_LAYOUT,
...
# Top tabs callback
@app.callback(Output('tabs-content', 'children'),
[Input('tabs-main', 'value')])
def render_content(tab):
if tab == 'tab-intro':
return tab_intro_layout
elif tab == 'tab-basic':
return tab_basic_layout
elif tab == 'tab-files':
return tab_files_layout
...
Now, on ‘files’ tab I have a file upload component and on successful operation on a file (adding, removing) I have a dbc.Toast
reporting result of the operation:
# files - update files table
@app.callback(
[
Output(component_id='upload-error-modal', component_property='style'),
Output(component_id='upload-error-message', component_property='children'),
Output(component_id='files-table', component_property='data'),
Output(component_id='toast-div', component_property='children'),
Output(component_id='upload-wait-div', component_property='children')
],
[
Input('session-id', 'children'),
Input('upload-data', 'contents'),
Input('upload-error-close-button', 'n_clicks'),
Input('files-table', 'data_previous')
],
[
State('upload-data', 'filename'),
State('files-table', 'data')
]
)
def update_files_table(session_id, upload_data_contents, error_close_button_nclicks,
data_previous, filename, data):
...
if removed_filename:
return {'display': 'none'}, '', data, make_toast_file_op(removed_filename, 'File removed.'), filename
def make_toast_file_op(filename, message):
return dbc.Toast([html.P(filename, className="mb-0")],
header=message,
className='toast',
headerClassName='toast-header',
bodyClassName='toast-body',
duration=3500)
Now on file upload or removal a Toast
is displayed and it vanishes after 3.5s.
However, if I switch to another tab, say tab-basic
before a Toast vanishes, it seems like a wrong layout is updated and this results in error:
An object was provided as `children` instead of a component, string, or number (or list of those). Check the children property that looks something like:
As long as I do not switch to another tab and wait until the Toast disappears, there’s no error.
The detailed error message seems to indicate that it is indeed layout of tab-basic
(when I switched to that tab to get the error) and not the layout of tab-files
.
How can I fix that?