dash
dash copied to clipboard
[BUG] aio components custom attributes not passed down.
Describe your context
dash 2.3.1
dash-core-components 2.0.0
dash-html-components 2.0.0
dash-labs 1.0.3
dash-table 5.0.0
Following six line demonstrator works with static layout:
app.layout = layout()
but fails to initialise when invoked dynamically:
app.layout = layout
The issue is with the method simple_clone(), in dash.py/L566. The Dash layout clone method fails to pass in the value total_items=100. This is significant problem since the sub-classing the standard Dash components is used extensively when implementing the reusable components AIO pattern.
class MyDiv(html.Div):
def __init__(self, children=None, className='some-class', total_items=None, page_size=10):
# Fails with TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'
pages = total_items / page_size
print(pages)
super().__init__(pages, className=className)
def layout():
return MyDiv(total_items=100)
With this code, you can extend the component with new props.
class MyDiv(html.Div):
def __init__(self, children=None, className='some-class', total_items=None, page_size=10):
# Fails with TypeError: unsupported operand type(s) for /: 'NoneType' and 'int'
pages = total_items / page_size
print(pages)
super().__init__(pages, className=className)
self._prop_names.extend(["total_items","page_size"])
self.total_items=total_items
self.page_size=page_size
Thanks for bringing this to our attention @stevej2608 - and nice find @nickmelnikov82! I'd consider your solution a hack though, as we don't want users depending on internals like _prop_names that may have other undocumented effects or might break later. A more robust workaround would be to create app.validation_layout
I think the ideal solution here would be to rewrite simple_clone so we don't call the constructor for the class we find. Two options occur to me:
- Instantiate base components (maybe via some special-purpose class like
ComponentClonethat we exclude from being registered) that recreates the required internals ofhtml.Div.__init__(or whatever Dash component) by pulling attrs out of the existing component. - Figure out the correct auto-generated Dash component class by traversing the class hierarchy, and instantiate that.