table
table copied to clipboard
table-core throw errors when trying to call table table.getHeaderGroups()
Describe the bug
I am trying to use table-core
in our application and there were a few hiccups.
Issues
1. Inconsistent between documentation and code
On the documentation table
API documentation, state
and onStateChange
are apparently optional when calling createTable
. However, they are required on the latest [email protected]
I was a bit confused between TableOptions
and TableOptionsResolved
.
https://github.com/TanStack/table/blob/af00c821b7943bc0f6d62a19b3ad514e3f315d75/packages/table-core/src/core/table.ts#L114
ℹ️ createTable
is accepting TableOptionsResolved
with state
is required. Where by TableOptions
has state
as optional. May I know why we need both types?
2. Error throw when calling table.getHeaderGroups()
Because of the type errors on 1), I supplied the state
as an empty object and onStateChange
as an empty arrow function. The full source code can find at codesandbox, I followed the react basic example.
table = createTable({
data,
columns,
state: {},
onStateChange: () => {},
getCoreRowModel: getCoreRowModel(),
renderFallbackValue: null,
});
When trying to use table.getHeaderGroups()
, it immediately throws errors
core.mjs:7643 ERROR TypeError: Cannot read properties of undefined (reading 'left')
at index.production.js:11:2759
at Object.getHeaderGroups (index.production.js:11:601)
If I try to console.log
console.log("state ", table.getState());
console.log("initial state ", table.initialState);
Only initialState
have an initial value and state
is having an empty object.
❌ Where is the issue
After looking into table-core source code, I found that core/headers.ts#L119 is trying to access to table.getState().columnPinning.left
. Because table.getState()
is an empty object, therefore columnPinning
is undedefined and it CAN't access left
.
✅ Workaround
- Try to set the state with
initialState
before invoking anything else, it works!
// ✅ work well
table.setOptions(prev => ({
...prev,
state: {
...prev.state,
...this.table.initialState
}
}))
console.log('initial table state', this.table.state);
That's how the React wrapper did under the hood as well. Therefore if a user wants to use table-core
, does it mean I have to set the state with initialState
every time?
https://github.com/TanStack/table/blob/af00c821b7943bc0f6d62a19b3ad514e3f315d75/packages/react-table/src/index.tsx#L71
- Strangely, I thought calling
table.setState
would do the same, but it DOESN'T work.
// ❌ doesn't work
this.table.setState(prev => ({
...prev,
...this.table.initialState
}))
Questions
- If
state
andonStateChange
are required, which means the documentation is NOT up to date. Am I right to say that? - What is the different between
TableOptions
andTableOptionsResolved
? - By following the doc freshly for
table-core
, do I have to calltable.setOptions
withinitialState
every time I want to usetable-core
? If it is, either the documentation needs to be updated, or the code needs to fix that.
Your minimal, reproducible example
https://codesandbox.io/s/tanstack-table-core-h86ggk?file=/src/index.ts:1702-1725
Steps to reproduce
-
npm install @tanstack/table-core
- Copy the following code
Toggle code ➡️
import {
createColumnHelper,
createTable,
getCoreRowModel
} from "@tanstack/table-core";
type Person = {
firstName: string;
lastName: string;
age: number;
visits: number;
status: string;
progress: number;
};
const data: Person[] = [
{
firstName: "tanner",
lastName: "linsley",
age: 24,
visits: 100,
status: "In Relationship",
progress: 50
},
{
firstName: "tandy",
lastName: "miller",
age: 40,
visits: 40,
status: "Single",
progress: 80
},
{
firstName: "joe",
lastName: "dirte",
age: 45,
visits: 20,
status: "Complicated",
progress: 10
}
];
const columnHelper = createColumnHelper<Person>();
const columns = [
columnHelper.accessor("firstName", {
cell: (info) => info.getValue(),
footer: (info) => info.column.id
}),
columnHelper.accessor((row) => row.lastName, {
id: "lastName",
cell: (info) => info.getValue(),
header: () => "Last Name",
footer: (info) => info.column.id
}),
columnHelper.accessor("age", {
header: () => "Age",
cell: (info) => info.renderValue(),
footer: (info) => info.column.id
}),
columnHelper.accessor("visits", {
header: () => "Visits",
footer: (info) => info.column.id
}),
columnHelper.accessor("status", {
header: "Status",
footer: (info) => info.column.id
}),
columnHelper.accessor("progress", {
header: "Profile Progress",
footer: (info) => info.column.id
})
];
const table = createTable({
data,
columns,
state: {},
onStateChange: () => {},
getCoreRowModel: getCoreRowModel(),
renderFallbackValue: null
});
// vvvv Immediate issues here
console.log(table.getHeaderGroups());
- You'll see the errors
Expected behavior
If I supplied state: {}
, the library would have set state
to use initialState
under the hood.
How often does this bug happen?
No response
Screenshots or Videos
No response
Platform
- macOS, codesanbox Vanilla TS project, Angular CLI created project
react-table version
8.5.13
TypeScript version
No response
Additional context
No response
Terms & Code of Conduct
- [X] I agree to follow this project's Code of Conduct
- [X] I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
Hi @trungk18 I am trying to implement table/core for angular as well, but we use Angular 8 on our project, and I had to rewrite all the core stuff and see how it works under the hood
let me share my workaround.
First I've created a wrapper service for that.
then I use it to create a table instance.
From the first screen, you'll see that you have to add the initial state to the table before doing anything else. You are getting all necessary fields when you call createTable (from table/core)
I recently tried to implement the table core package into a Stencil.js project. After a while I came up with a working implementation. Check this repository, it might give you some ideas for fixing your issue as well. Specifically I think that you are missing the flexRender() method. Check the stencil-adapter.tsx
inside my repo.
state
and onStateChange
should only be optional if using a framework adapter. we should correct this in the docs.