How to fix: Cannot read properties of undefined (reading 'type')

Hi, I know there are similar topics, but I haven’t found a solution yet. I have a multi-page dash app, which contains background callbacks that allow changing the states of dropdowns (placeholder, disabled, value, options) under certain conditions. in most callbacks, there is running in the callback execution. the problem is that if I go to another page without waiting for the end of the action, I get this error. I understand that he wants me to substitute the result of the unfinished callback in an unnecessary place, because he does not find the right one. maybe someone knows an option on how to stop callback execution when switching to a new page, since it is not possible to abandon background callbacks. I tried to link the pathname of the active page to the execution of the function, but this does not affect the callback. what did you do:

if pathname == '/':
        try:
            some func()
        except:
            raise PreventUpdate
    else:
        return dash.no_update

this did not solve the problem
errors:

Cannot read properties of undefined (reading 'type')

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:

You can cancel a background callback:

Take a look at the third example. Maybe you can trigger the cancel via a dcc.Location()

maybe there are some thoughts on how you can cancel the background callback by changing the page?

I think this works, at least you’ll see in the prompt that the callback gets canceled if changing the page:

app.py

import dash
from dash import html, dcc, DiskcacheManager, Input, Output, clientside_callback
import dash_bootstrap_components as dbc
import diskcache

cache = diskcache.Cache("./cache")
background_callback_manager = DiskcacheManager(cache)

external_stylesheets = [
    dbc.themes.SLATE
]

# initiate app
app = dash.Dash(
    __name__,
    use_pages=True,
    external_stylesheets=external_stylesheets,
    background_callback_manager=background_callback_manager
)

# create a navbar
navbar = dbc.Navbar(
    id='navbar',
    children=[
        dbc.Nav(
            dbc.DropdownMenu(
                [
                    dbc.DropdownMenuItem(
                        children=page['name'],
                        href=page['path']
                    )
                    for page in dash.page_registry.values()
                    if page['name'] != 'Not found 404'
                ],
                align_end=False,
                label='Menu',
                color='primary',
            ),
            navbar=True,
        ),
    ],
    color='primary',
    className='mb-0',
    # ^^ no margin on bottom
    style={'height': '50px'}
)

app.layout = html.Div(
    [
        navbar,
        dash.page_container,
        dcc.Location(id='url'),
        dcc.Store(id='changed_url', storage_type='session'),

    ],
)


clientside_callback(
    """
    function(_) {
        return "uuid-" + ((new Date).getTime().toString(16) + Math.floor(1E7*Math.random()).toString(16));
    }
    """,
    Output('changed_url', 'data'),
    Input('url', 'href')
)


if __name__ == "__main__":
    app.run(debug=False, port=8056)

home.py

from dash import register_page, html, callback, Input, Output
from dash.exceptions import PreventUpdate
import dash_bootstrap_components as dbc
import time

# register page in the registry
register_page(__name__, path="/")

layout = html.Div(
    id='home_out',
    children=[
        html.Button(
            id='btn',
            n_clicks=0,
            children='start_callback',
            style={'margin-top': '100px'}),
        html.Button(
            id='cancel',
            children='cancel callback'
        ),
        html.Div(id='indicator'),
        html.Div(id='container'),
        html.Div(id='canceled')
    ]
)


@callback(
    output=Output("container", "children"),
    inputs=Input("btn", "n_clicks"),
    background=True,
    running=[
        (Output("indicator", "children"), dbc.Spinner(), ''),
    ],
    cancel=[
        Input("changed_url", "data"),
        Input("cancel", "n_clicks")
    ],
    prevent_initial_call=True
)
def update_clicks(click):
    if not click:
        raise PreventUpdate

    time.sleep(5.0)
    return [f"background callback output"]

page_1.py

from dash import register_page, html

# register page in the registry
register_page(__name__, path="/page_1")

layout = html.Div(
    children=[
        html.Div(
            id='container_page_1',
            children='Page 1'
        )
    ]
)

mred background cb

Thank you, yes. I also wrote my own logic and it is similar to yours. indeed, that removed the error. but there is a nuance. I have dropdowns on my pages. and where I have inserted these adjustments now, I mean I added cancel, when switching to another page, it is changed in the dropdown state. I’ll explain now.
page1.py

dcc.Location(id='url1', refresh=False),
        dcc.Store(id='store1', storage_type='session'),
        dbc.Row([
            dbc.Col(dcc.Dropdown(options=['A1', 'A2'], placeholder="Select", id=dd1',),),
            dbc.Col(dcc.Dropdown(id='dd2',  placeholder="Select", disabled=True), ),
        ])
clientside_callback(
    """
    function(_) {
        return "uuid-" + ((new Date).getTime().toString(16) + Math.floor(1E7*Math.random()).toString(16));
    }
    """,
    Output('store1, 'data'),
    Input('url1', 'href')
)
@dash.callback(
    output=Output('dd2', 'options'),
    inputs=Input('dd1', 'value'),
    state=[State('url1', 'pathname'),
        # State('store-pk', 'data'),],
    background=True,
    running=[
        (Output('dd2', 'placeholder'), 'Loading...', 'Select ',),
        (Output('pdd2', 'disabled'), True, False), ],
    cancel=[Input("url2", "data"),],
    prevent_initial_call=True, )
def choose(dd1, path):
    if path == '/page1':
        try:
            if not dd1:
                raise PreventUpdate
            elif dd1:
                options = some func()
                return options
        except:
            raise PreventUpdate
    else:
        return dash.no_update

page2

dcc.Location(id='url2', refresh=False),
dcc.Store(id='store2', storage_type='session'),
        dbc.Row([
            dbc.Col( dcc.Dropdown([some values], id='dd_1', placeholder='Select' ),  ),
            dbc.Col(dcc.Dropdown( id='dd_2', placeholder='Select', disabled=True),  ),])

after switching to page 2, when callback - dropdown 2 is incomplete, page 2 becomes disabled=False, although it should remain True

the error persists anyway. when switching to another page, cancel does not work and what running receives at the output tries to transfer to the data already on another page
my cancelable callback:

@dash.callback(
    output=Output('dropdown2', 'options'),
    inputs=Input('dropdown1', 'value'),
    background=True,
    running=[ (Output('dropdown2', 'placeholder'), 'Loading...', 'Select',),
        (Output('dropdown2', 'disabled'), True, False),],
    cancel=[Input("_pages_location", 'pathname'),],
    prevent_initial_call=True,
    # manager=background_callback_manager
)
def choose_cnt(value):  
    try:
        if not value:
            raise PreventUpdate
        elif value:
            options = some func()
            return options
    except:
        raise PreventUpdate

image

I had the same error at some point, but with the example above I didn’t get any errors, at least in my tests :thinking:

in the example that you threw off, there really are no errors. but if I do this in my app, everything breaks

image
can you help me understand what I did wrong here that I couldn’t load layout? I decided to rewrite the code
received:
image

You have to move the for page in... outside of the rounded bracket of the dbc.NavItem()

image
if I do so, he swears at the comma after for
and I have further NavItem

of course :wink:

You could wrap the first items in a html.Div() and all other NavItems into another. Or just add the two lists.

If you post your code so that it can be copy pasted one could help…

navbar = dbc.NavbarSimple(
    children=[
        dbc.NavItem(
            dbc.NavLink(page['name'], href=page["path"])
        ) for page in dash.page_registry.values(),  
        dbc.NavItem(
            elms_labels.get_navbar_label(None, rg_utils.get_version()),
            id="navbar_label_cnt",
        ),
])

thanks

navbar = dbc.NavbarSimple(
    children=[
        html.Div(
            [
                dbc.NavItem(dbc.NavLink(page['name'], href=page["path"]))
                for page in dash.page_registry.values()
            ]
        ),
        dbc.NavItem(
            elms_labels.get_navbar_label(None, rg_utils.get_version()),
            id="navbar_label_cnt",
        ),
    ]
)

this should work too:

navbar = dbc.NavbarSimple(
    children=[
                 dbc.NavItem(dbc.NavLink(page['name'], href=page["path"]))
                 for page in dash.page_registry.values()
             ] +
             [
                 dbc.NavItem(
                     elms_labels.get_navbar_label(None, rg_utils.get_version()),
                     id="navbar_label_cnt",
                 )
             ],
)

yes it worked, the only thing that didn’t work out was this Div stretched down. don’t know how to bring it to its original position?
the menu changed from horizontal to vertical

Hi! With the second option from above you should not have this issue.

yes, indeed. thank you. I’m sorry, but I’m having problems with registry_page. I created the app a little differently. Can I ask you another question? why might layout not load? I tried it in different ways, now I will make a screenshot. but layout doesn’t load

app.py:

app.layout = dbc.Container(
    id="root",
    fluid=True,
    class_name="mw-100",  
    children=[
        dcc.Location(id="url", refresh=False),
        dcc.Store(id='changed_url', storage_type='session'),
        navbar,
        dbc.Row([html.P()]),  
        dash.page_container,  
    ],
)

page1.py:

register_page('Page1', path="/page1", order=0)

image

these are the options, as I tried to prescribe layout. but in the end an empty field

help me understand why layout is not loaded!!!

On page1.py change to:

layout = dbc.Container([
    your rows and columns
])

something incomprehensible is happening, and html.Div was prescribed, and dlc.Container is now prescribed. and no layout, a blank screen. I can’t understand anything

no exception or trackback with an error. just a white screen, the menu loads and that’s it