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

DataTable runtime row type is lost #667

Open
brunnerh opened this issue Jun 2, 2021 · 4 comments · May be fixed by #816
Open

DataTable runtime row type is lost #667

brunnerh opened this issue Jun 2, 2021 · 4 comments · May be fixed by #816

Comments

@brunnerh
Copy link
Contributor

brunnerh commented Jun 2, 2021

The DataTable component uses a spread operation internally which loses all non-enumerated properties and the original type:

$: rows = rows.map((row) => ({
  ...row,
  cells: headerKeys.map((key, index) => ({
    key,
    value: resolvePath(row, key, ""),
    display: headers[index].display,
  })),
}));

E.g. functions of the prototype will be gone:

var x = { log() { console.log('!') } }
var y = { ...x }
y.log();
// logs !

class X { log() { console.log('!') } }
var x = new X();
var y = { ...x }
y.log()
// TypeError: y.log is not a function

I would recommend assigning the original row to a property instead of or additionally to spreading it to prevent this.

In my particular use case the row is a Proxy, which becomes mostly useless after the spread. Having the original type might also be useful for type-based operations using instanceof.

@brunnerh
Copy link
Contributor Author

brunnerh commented Jun 2, 2021

Also, this merge operation overwrites any cells property on the row, which could potentially lead to unexpected behavior when trying to access this via the injected row:

<script>
  import { DataTable } from "carbon-components-svelte";

  const headers = [
    { key: 'organism', value: "Organism" },
    { key: 'cells', value: "Cells" }
  ];

  const rows = [
    { id: 0, organism: "Elegans - Adult male", cells: 1031 },
    { id: 1, organism: "Elegans - Adult hermaphrodite", cells: 959 },
    { id: 2, organism: "Elegans - Hatched larvae", cells: 558 },
  ];
</script>

<DataTable {headers} {rows} title="row.cells unexpected">
  <span slot="cell" let:row let:cell>
    {#if cell.key == 'cells'}
      {row.cells}
    {:else}
      {cell.value}
    {/if}
  </span>
</DataTable>

image

@brunnerh brunnerh changed the title DataTable row type is lost DataTable runtime row type is lost Apr 20, 2022
@metonym
Copy link
Collaborator

metonym commented Jun 5, 2022

In #1179, the implementation changed so that rows is not modified. cells is no longer written to the rows prop.

However, this is still an issue if using slotted cells, as row.cells will still override the cells property. This is addressed by 5d61929.

@metonym
Copy link
Collaborator

metonym commented Jun 5, 2022

@brunnerh Can you provide a simple repo of your use case to illustrate the first problem?

metonym added a commit that referenced this issue Jun 5, 2022
* refactor(data-table): remove unneeded third argument from resolvePath call

* fix(data-table): do not overwrite `cells` property (#667)

* perf(data-table): early return if path in object when resolving path
@brunnerh
Copy link
Contributor Author

brunnerh commented Jun 5, 2022

@metonym Do you mean the type being lost?

This illustrates two use cases when using classes: REPL

  • Function on prototype is lost ("Show" button)
  • Row object identity is lost ("Delete" button)

I currently cannot access the original project using proxies, but this should be pretty similar: REPL
The cell value is read correctly from the underlying proxy but the row cannot be used to read or update the value.
To fixe the marked errors, the underlying data or the original rows have to be accessed instead.
E.g. row[cell.key][row.property] => data[cell.key][row.property]

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

Successfully merging a pull request may close this issue.

2 participants