table icon indicating copy to clipboard operation
table copied to clipboard

Global filter doesn't run when accessor key points to an object

Open francislavoie opened this issue 2 years ago • 16 comments

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.

francislavoie avatar Jan 24 '23 12:01 francislavoie

+1, trying to update to v8 and I run into this issue. Seems like a big oversight.

anthonyma94 avatar Feb 09 '23 23:02 anthonyma94

@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.

anthonyma94 avatar Feb 10 '23 16:02 anthonyma94

+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

THowland1 avatar Feb 27 '23 12:02 THowland1

+1

eliasmelgaco avatar Mar 28 '23 17:03 eliasmelgaco

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} />
}

basememara avatar Apr 02 '23 22:04 basememara

+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

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.

tannerbaum avatar Apr 06 '23 12:04 tannerbaum

maybe the AccessorFn should document somehow that its return value should be primitive

chiptus avatar May 09 '23 03:05 chiptus

Any updates on this?

Or does the TanTable not support objects as values?

FlemmingBehrend avatar Jun 01 '23 14:06 FlemmingBehrend

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 avatar Jun 01 '23 18:06 KevinVandy

@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.

francislavoie avatar Jun 01 '23 21:06 francislavoie

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.

FlemmingBehrend avatar Jun 02 '23 08:06 FlemmingBehrend

Added some commentary to #4919 that is potentially relevant to this.

Hephaestian avatar Jan 08 '24 13:01 Hephaestian

+1

LiMao00 avatar Jul 08 '24 09:07 LiMao00