Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] DeserializationError when trying to change a DataTable's columns with CustomJS #11422

Closed
charlesbluca opened this issue Jul 15, 2021 · 1 comment · Fixed by #11469
Closed

Comments

@charlesbluca
Copy link

ALL software version info (bokeh, python, notebook, OS, browser, any other relevant packages)

  • Bokeh 2.3.2
  • Python 3.8.10

Description of expected behavior and the observed behavior

I am trying to use a CheckboxButtonGroup widget to toggle the visibility of columns in a DataTable. My approach to this is to use some CustomJS that adds or removes columns from the table in question upon clicking the button. This works fine, and the table responds as expected. However, I get serialization errors in console every time I click the button.

For context, this issue came up while working on dask/distributed#4614.

Complete, minimal, self-contained example code that reproduces the issue

# example.py

from datetime import date
from random import randint

from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import (
        ColumnDataSource,
        DataTable,
        DateFormatter,
        TableColumn,
        CheckboxButtonGroup,
        CustomJS
    )
from bokeh.plotting import curdoc

data = dict(
        dates=[date(2014, 3, i+1) for i in range(10)],
        downloads=[randint(0, 100) for i in range(10)],
    )
source = ColumnDataSource(data)

columns = [
        TableColumn(field="dates", title="Date", formatter=DateFormatter()),
        TableColumn(field="downloads", title="Downloads"),
    ]
data_table = DataTable(source=source, columns=columns, width=400, height=280)

column_choice = CheckboxButtonGroup(
    labels=[
        "Date",
        "Downloads"
    ],
    active=[0, 1],
)
column_choice.js_on_click(
    CustomJS(
        args=dict(
            table=data_table, columns=columns
        ),
        code="""
            var visible_columns = []
            for (var i = 0; i < this.active.length; i++) {
                visible_columns.push(columns[this.active[i]])
            }
            table.columns = visible_columns;
        """,
    )
)

curdoc().add_root(column(column_choice, data_table))
$ bokeh serve --show example.py

Stack traceback and/or browser JavaScript console output

On button click:

bokeh.server.protocol_handler - ERROR - error handling message
 message: Message 'PATCH-DOC' content: {'events': [{'kind': 'ModelChanged', 'model': {'id': '1371'}, 'attr': 'columns', 'new': [{'id': '1345'}, {'id': '1346'}, {'id': '1347'}, {'id': '1348'}, {'id': '1349'}, {'id': '1350'}, {'id': '1351'}, {'id': '1352'}]}], 'references': []} 
 error: DeserializationError("Instance(TableColumn) failed to deserialize reference to {'id': '1345'}")
Traceback (most recent call last):
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/server/protocol_handler.py", line 90, in handle
    work = await handler(message, connection)
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/server/session.py", line 67, in _needs_document_lock_wrapper
    result = func(self, *args, **kwargs)
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/server/session.py", line 261, in _handle_patch
    message.apply_to_document(self.document, self)
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/protocol/messages/patch_doc.py", line 100, in apply_to_document
    doc._with_self_as_curdoc(lambda: doc.apply_json_patch(self.content, setter))
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/document/document.py", line 1198, in _with_self_as_curdoc
    return f()
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/protocol/messages/patch_doc.py", line 100, in <lambda>
    doc._with_self_as_curdoc(lambda: doc.apply_json_patch(self.content, setter))
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/document/document.py", line 411, in apply_json_patch
    patched_obj.set_from_json(attr, value, models=references, setter=setter)
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/core/has_props.py", line 412, in set_from_json
    descriptor.set_from_json(self, json, models, setter)
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/core/property/descriptors.py", line 623, in set_from_json
    return super().set_from_json(obj, self.property.from_json(json, models), models, setter)
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/core/property/container.py", line 70, in from_json
    return self._new_instance([ self.item_type.from_json(item, models) for item in json ])
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/core/property/container.py", line 70, in <listcomp>
    return self._new_instance([ self.item_type.from_json(item, models) for item in json ])
  File "/home/charlesbluca/miniconda3/envs/dask-distributed/lib/python3.8/site-packages/bokeh/core/property/instance.py", line 93, in from_json
    raise DeserializationError(f"{self} failed to deserialize reference to {json}")
bokeh.core.property.bases.DeserializationError: Instance(TableColumn) failed to deserialize reference to {'id': '1345'}
@charlesbluca charlesbluca changed the title [BUG] [BUG] DeserializationError when trying to change a DataTable's columns with CustomJS Jul 15, 2021
@bryevdv bryevdv added this to the next milestone Jul 15, 2021
@mattpap mattpap modified the milestones: next, 2.4 Aug 2, 2021
@bryevdv
Copy link
Member

bryevdv commented Sep 4, 2021

prematurely adding completed to signal a PR breaks the logic of the milestone checker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants