Skip to content

Persistence not working when layout is list of components #3147

Open
@valentjn

Description

@valentjn

Describe your context

dash                      2.18.2
dash-bootstrap-components 1.7.1
dash-core-components      2.0.0
dash-html-components      2.0.0
dash-table                5.0.0
- OS: Linux
- Browser: Firefox
- Version: 134.0.1

Describe the bug

Input persistence with persistence=True is not working when using a list of components as layout.

Steps to reproduce

  1. Run the following minimal example:
import dash
app = dash.Dash()
input = dash.dcc.Input(id="my_input", persistence=True)
app.layout = [input]  # does not work
#app.layout = input  # works
#app.layout = dash.html.Div([input])  # works
if __name__ == "__main__": app.run(debug=True)
  1. Open http://127.0.0.1:8050/ in a browser.
  2. Enter something in the input field.
  3. Reload the page.

Actual behavior

The input field is empty after reloading.

Expected behavior

The input field contains the previously entered string.

Additional information

  • When replacing the app.layout line with one of the two other lines denoted with # works, the bug does not surface (i.e., the entered string is persisted correctly).
  • Although the documentation of dash.Dash.layout says the layout must be a component or a function returning a component (it doesn't say a list of components is allowed), many examples in the Dash documentation use a list of components, e.g., the Hello World example. dash._validate.validate_layout_type() allows lists:

    dash/dash/_validate.py

    Lines 400 to 404 in 7c03187

    def validate_layout_type(value):
    if not isinstance(
    value, (Component, patch_collections_abc("Callable"), list, tuple)
    ):
    raise exceptions.NoLayoutException(
  • The bug is probably caused by this check:
    export function applyPersistence(layout, dispatch) {
    if (type(layout) !== 'Object' || !layout.props) {
    return layout;
    }
    I don't know much about JavaScript, but in a quick debugging session, layout seemed to be an array instead of an object, therefore skipping the persistence restore process.
  • The bug also surfaces in much more complicated layouts, i.e., when the input is somewhere deep down. It was pretty hard to find out it was due to the top-level list. Everything else seems to be working when using a list, just the persistence wasn't.

Metadata

Metadata

Assignees

Labels

P2considered for next cyclebugsomething broken

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions