evidence icon indicating copy to clipboard operation
evidence copied to clipboard

[Bug]: DataTable gets into undefined state showing wrong data when columns change dynamically

Open olegam opened this issue 1 year ago • 5 comments

Describe the bug

I'm using the DataTable as a pivot table to show monthly aggregated data in combination with a Dropdown to filter the data. When filtering the data the columns change and this causes the DataTable to crash and show invalid data.

From the browser console log (e.g. column with id: "2024-04-01" not found) it looks like there might be an assumption in the DataTable implementation that the columns will stay constant and not update with the data. This assumption is not true in some use cases, including when used as a pivot table.

Steps to Reproduce

Here is an example page to reproduce the issue. Just select a few different values in the Dropdown and the DataTable will get into the inconsistent state.

Image

---
title: Pivot Table Bug
---

This page demonstrates a bug in DataTable when used as a pivot table where the columns change dynamically based on user selections in a Dropdown. After selecting different values in the dropdown, the table end up in a bad state where the columns are not updated correctly. The browser console shows errors like "client.js?v=637732ed:2684 column with id: "2024-01-01" not found".

<Dropdown name=selected_customer>
    <DropdownOption value="John Smith" />
    <DropdownOption value="Mary Johnson" />
    <DropdownOption value="Peter Brown" />
</Dropdown>

```sql orders_pivoted
WITH sample_data AS (
  SELECT * FROM (
    VALUES
    (1, 'John Smith', '2024-01-15', 45),
    (2, 'John Smith', '2024-04-15', 82),
    (3, 'Mary Johnson', '2024-01-20', 33),
    (4, 'Mary Johnson', '2024-01-01', 67),
    (5, 'Peter Brown', '2024-02-01', 91),
    (6, 'Peter Brown', '2024-02-15', 28),
    (7, 'John Smith', '2024-02-15', 55),
    (8, 'Mary Johnson', '2024-01-20', 74),
    (9, 'Peter Brown', '2024-03-01', 63),
    (10, 'Mary Johnson', '2024-03-05', 42),
    (11, 'John Smith', '2024-03-10', 88),
    (12, 'Peter Brown', '2024-01-25', 37),
    (13, 'Mary Johnson', '2024-05-15', 95)
  ) AS t(order_id, customer_name, date, value)
),
base AS (
  SELECT 
    customer_name,
    DATE_TRUNC('month', date::date) as month,
    value
  FROM sample_data
  WHERE customer_name = '${inputs.selected_customer.value}'
)
SELECT *
FROM (
  PIVOT base
  ON month
  USING sum(value)
  GROUP BY customer_name
)
ORDER BY customer_name
```


<DataTable 
    data={orders_pivoted} 
    rows=all 
    sortable={true}
/>

Logs

Here is a console log from the browser:
client.js?v=637732ed:2684 <SortIcon> was created without expected prop 'ascending'
5
client.js?v=637732ed:2684 <Column> was created with unknown prop 'identifier'
5
client.js?v=637732ed:2684 <SortIcon> was created without expected prop 'ascending'
3
client.js?v=637732ed:2684 <DropdownOptionDisplay> was created with unknown prop 'id'
+page.md:25 column with id: "2024-05-01" not found
+page.md:25 column with id: "2024-02-01" not found
+page.md:25 column with id: "2024-02-01" not found
+page.md:25 column with id: "2024-04-01" not found
+page.md:25 column with id: "2024-04-01" not found
+page.md:25 column with id: "2024-02-01" not found
+page.md:25 column with id: "2024-04-01" not found
3
client.js?v=637732ed:2684 <DropdownOptionDisplay> was created with unknown prop 'id'
+page.md:25 column with id: "2024-05-01" not found
+page.md:25 column with id: "2024-05-01" not found
+page.md:25 column with id: "2024-05-01" not found
+page.md:25 column with id: "2024-05-01" not found
+page.md:25 column with id: "2024-05-01" not found
+page.md:25 column with id: "2024-05-01" not found
3
client.js?v=637732ed:2684 <DropdownOptionDisplay> was created with unknown prop 'id'
+page.md:25 column with id: "2024-04-01" not found
+page.md:25 <Column> was created with unknown prop 'identifier'
2
+page.md:25 <SortIcon> was created without expected prop 'ascending'

System Info


Severity

serious, but I can work around it

Additional Information, or Workarounds

I'm interested in any kind of workaround. Can I make DataTable refresh entirely when the dataset changes instead of trying to update incrementally? Can I work around this by forking DataTable?

olegam avatar Jan 09 '25 22:01 olegam

You might be able to use a svelte {#key} block to destroy and recreate the component every time your input changes as a workaround

https://svelte.dev/docs/svelte/key

archiewood avatar Jan 10 '25 02:01 archiewood

How would you use the {#key} with the example above? I have tried this, but it does not seem to have any effect:

{#key inputs.selected_customer.value}
<DataTable 
    data={orders_pivoted} 
    rows=all 
    sortable={true}
/>
{/key}

Would I need to fork DataTable and use {#key} in the implementation?

olegam avatar Jan 10 '25 08:01 olegam

This works for me

{#key orders_pivoted}
<DataTable 
    data={orders_pivoted} 
    rows=all 
    sortable={true}
/>
{/key}

Image

archiewood avatar Jan 10 '25 17:01 archiewood

Thanks. This seems to solve the issue for me too 🙌

olegam avatar Jan 13 '25 08:01 olegam

Reopening as I think this is still a valid bug. The {#key} approach is a workaround

archiewood avatar Jan 13 '25 14:01 archiewood