Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Change values to value in Checklist? #133

Closed
ned2 opened this issue Dec 22, 2017 · 4 comments
Closed

Change values to value in Checklist? #133

ned2 opened this issue Dec 22, 2017 · 4 comments
Labels
dash-type-bug Something isn't working as intended

Comments

@ned2
Copy link
Contributor

ned2 commented Dec 22, 2017

Currently, not providing an initial value for the values attribute of dcc.Checklist results in the front end displaying "Error loading layout" and an obscure Exception on the backend which does not shed much light on the source of the problem (included at end). In order to have no checkboxes selected (and avoid this issue), you must provide an initial value of values=[], but I think it's a reasonable assumption that the default value would have this behavior and so could be omitted.

Relevant post on the forum: https://community.plot.ly/t/filling-a-checklist-through-a-callback/7435

The current exception:

Traceback (most recent call last):
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/flask/app.py", l
ine 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/flask/app.py", l
ine 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/flask/app.py", l
ine 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/flask/_compat.py
", line 33, in reraise
    raise value
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/flask/app.py", l
ine 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/flask/app.py", l
ine 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/flask/app.py", l
ine 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/flask/_compat.py
", line 33, in reraise
    raise value
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/flask/app.py", l
ine 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/flask/app.py", l
ine 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/dash/dash.py", l
ine 155, in serve_layout
    cls=plotly.utils.PlotlyJSONEncoder),
  File "/home/ned/.pyenv/versions/3.6.3/lib/python3.6/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/plotly/utils.py"
, line 136, in encode
    encoded_o = super(PlotlyJSONEncoder, self).encode(o)
  File "/home/ned/.pyenv/versions/3.6.3/lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/home/ned/.pyenv/versions/3.6.3/lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/home/ned/.pyenv/versions/3.6.3/envs/app/lib/python3.6/site-packages/plotly/utils.py"
, line 204, in default
    return _json.JSONEncoder.default(self, obj)
  File "/home/ned/.pyenv/versions/3.6.3/lib/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'method' is not JSON serializable
@chriddyp chriddyp added dash-type-bug Something isn't working as intended dash-meta-good_first_issue and removed dash-meta-good_first_issue labels Dec 22, 2017
@chriddyp
Copy link
Member

Well, this is unfortunate. Dash components inherit from the Component class which inherits from the collections.MutableMapping abstract base class:
https://github.com/plotly/dash/blob/b61f0d371239ee5a6286ce539fab24d2d3de432a/dash/development/base_component.py#L13

This abstract base class implementation treats a nested component tree as a mapping between ids and components. So,

>>> c = html.Div([html.Div(id='grandchild'), html.Div([html.Div(id='great-grandchild')])])
>>> c.keys()
 ['grandchild', 'great-grandchild']
>>> c.values()
[Div(id='grandchild'), Div(id='great-grandchild')]

Which makes values a sort-of reserved attribute. The component's properties are available as attributes, so

>>> c = dcc.RadioItems(value=3)
>>> c.value
3
>>> c.options
AttributeError: 'RadioItems' object has no attribute 'options'

That AttributeError is used in several places in the component to determine if the attribute was supplied or not by the user (and therefore whether to serialize it or not).

In the case of the Checklist, values is an attribute from the parent component:

>>> c = dcc.Checklist(values=[3])
>>> c.values
[3]

But if it wasn't supplied, then instead of throwing an AttributeError, it returns the abstract base method function

>>> c = dcc.Checklist()
>>> values = c.values
>>> type(values)
instancemethod

So, we have 2 options:

  1. Ditch the abstract base method implementation
  2. Change property from values to value and do more checks in the Component for "reserved" or "forbidden" properties: pop, popitem, clear, update, setdefault, items, values, get (taken from https://docs.python.org/2/library/collections.html#collections-abstract-base-classes)

I think that I prefer 2.

@ned2
Copy link
Contributor Author

ned2 commented Dec 23, 2017

Ah I see, that certainly explains the obscure TypeError: Object of type 'method' is not JSON serializable.

I'm not familiar with the design considerations going into using the abstract base class, pulling it out seems like it would be a fairly major change for this one particular issue. Changing the name of the property to value is an API breaking change, however the silver lining is that it makes it consistent with all the other Core Components, which I think there is an argument to be made is preferable.

Seems like a reasonable solution to me.

@chriddyp chriddyp changed the title 'values' attribute in dcc.Checklist should be optional Change values to value in Checklist? Jul 10, 2018
chriddyp added a commit to plotly/dash-renderer that referenced this issue Apr 15, 2019
Checklist needs `values` defined atm
plotly/dash-core-components#133
@gwsampso
Copy link

looks like this is still outstanding? just running into this now

@alexcjohnson
Copy link
Collaborator

Oh I should close this... we changed to Checklist.value in #558 that was released with Dash v1.0 - what version are you using?

Also we removed the MutableMapping inheritance in plotly/dash#753

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
dash-type-bug Something isn't working as intended
Projects
None yet
Development

No branches or pull requests

4 participants