table
table copied to clipboard
Global filter doesn't run when accessor key points to an object
Describe the bug
If the accessor key points to an object in the data, then the global filter never gets invoked, even if I define a custom filter function.
This wasted a few hours of my time trying to track down why my global filter wasn't working. I find it very surprising that it would silently ignore my column.
Your minimal, reproducible example
https://codesandbox.io/p/sandbox/elegant-morning-i68tj7?file=%2Fsrc%2Fmain.tsx&selection=%5B%7B%22endColumn%22%3A17%2C%22endLineNumber%22%3A125%2C%22startColumn%22%3A17%2C%22startLineNumber%22%3A125%7D%5D
Steps to reproduce
Type things in the global filter, notice the rows are not filtered. Open the console, see that console.log() in fuzzyFilter is never called.
Expected behavior
If the accessor points to an object and there's a filter defined (either via globalFilterFn or a filterFn on the column), then it should still attempt to filter that column.
Or at the very least, there should be some kind of debug log if debug is turned on to explain why a column isn't getting filtered. There's really no observability to discover why the column is ignored.
The docs also make no mention that the column type would make a difference.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
Any
react-table version
8.7.6
TypeScript version
4.9.4
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.
+1, trying to update to v8 and I run into this issue. Seems like a big oversight.
@francislavoie I figured out why. It's very briefly mentioned in the column def guide that the accessor retrieves a primitive value, and that's the value used for filtering (and other functions). Once I created an accessor function that transforms the object to a string, global filtering works again.
For my use case, the only object being passed in is a dayjs object, so it's easy enough to transform it into a string (I'm doing that to display on-screen anyways). Your use case might be different.
Either way, I do think there should be better documentation about this potential issue, or some kind of error message when the accessor value is being accessed.
+1 for this issue
I used to be able to do a global search filter on an array column in v7.8.0, but now I cannot (v8.7.9).
The FilterFnOption type (for a filterFn of a ColumnDef) allows the string values: arrIncludes,
arrIncludesAll, arrIncludesSome. Which implies that filtering on array-type column values would work, but it does not.
Also, in the globalFilterFn callback passed into useReactTable, the function never runs with the columnId of the array-type column, so I can't even manually write a filter function that can access the array-type value
+1
This was driving me insane for awhile. My column value is an array and tried adding a filterFn function to my column def so I can hook in my filter logic for it. This was after trying to simply set it to arrIncludes since that implied it works on an array column. Nothing worked. After stumbling on this thread and flattening my array to a string it started searching the field but isn't a perfect search:
{
header: 'Tags',
accessorFn: (row) => row.tags.join(','),
cell: ({ row }) => <Tags values={row.original.tags} />
}
+1 for this issue
I used to be able to do a global search filter on an array column in v7.8.0, but now I cannot (v8.7.9).
The
FilterFnOptiontype (for afilterFnof a ColumnDef) allows the string values:arrIncludes,arrIncludesAll,arrIncludesSome. Which implies that filtering on array-type column values would work, but it does not. Also, in theglobalFilterFncallback passed intouseReactTable, the function never runs with thecolumnIdof the array-type column, so I can't even manually write a filter function that can access the array-type value
Yes exactly, the globalFilterFn never runs and no feedback is provided, so it's impossible to figure out this is the cause without finding this issue. No console logging from within, type warnings, debug settings on the hook, etc can help point the way.
My accessors were pointing to objects with the shape { value: any, error: boolean } so that the cell could access data via cell: (info) => info.getValue().value, and I could in the markup style the cells that have errors differently.
And just as a side note, as a newcomer to the library I have to say it seems very powerful but I am really struggling with the v8 documentation. v7/react-table seemed to have a bit more in terms of explanation and at least some of the examples were more focused on a specific topic rather than having 4 different table features on display at once.
maybe the AccessorFn should document somehow that its return value should be primitive
Any updates on this?
Or does the TanTable not support objects as values?
Any updates on this?
Or does the TanTable not support objects as values?
TanStack Table doesn't encourage accessors resolving to objects if you care about sorting filtering, or grouping. Those only work by default with resolved primitive values.
That's not to say you can't render complex values in a column though. You can still have multiple values in a custom cell render and access any data in the data row via row.original
@KevinVandy IMO it's fine if objects aren't considered, but I think it's wrong for the global filter to not work at all if any column is an object. I think it should either throw a error/warning, or skip that column and still filter the other non-object columns.
Any updates on this? Or does the TanTable not support objects as values?
TanStack Table doesn't encourage accessors resolving to objects if you care about sorting filtering, or grouping. Those only work by default with resolved primitive values.
That's not to say you can't render complex values in a column though. You can still have multiple values in a custom cell render and access any data in the data row via
row.original
Hi @KevinVandy
Is there another way to get cell specific "extra information" into the cell renderer?
Basically what I'm trying to do is the following:
The object structure I want to render have this type:
type Cell<T> = {
value: T
href? string;
target? string;
tooltip? string;
}
When defining the columns (for simplicity the example only have one column):
type TableData = {
name: Cell<string>;
}
const data: TableData[] = [
{
name: { value: 'John', href: 'www.google.com', target: '_blank', tooltip: 'Person John' }
},
{
name: { value: 'Doe', href: 'www.google.com', target: '_blank', tooltip: 'Person Doe' }
}
];
const columns = [
{
accessorKey: 'name', // If I put 'name.value' here the global filter function is called, but I loose access to href, target and tooltip
header: 'Name',
cell: CellRenderer, // this is a function that can handle rendering of links and tooltips
}
];
It would be nice if the globalFilterFn just received the TableData object in the value property and you could implement your own filter fn. Setting the accessor to an object would mean that you can not use the build in filters. This is fine as the build in filters are for primitive values.
Added some commentary to #4919 that is potentially relevant to this.
+1