Question about transformItems RefinementList widget

Hi,

It seems that when i would like to filter the result of my refinement, some features like limit or showMore act before transformItems.

For example, i would like to show only refinements that has more then 5 counts. I use transformItems to filter items.

transformItems: items => items.filter(item => {
        if (item.count < 5) {
             return false;
        }
        return true;
 }),

The problem is that limit or showMore don’t take care about the result of transformItems. It use only the predefine result of the refinement.

I have the same problem with panel hidden…

How could i handle this problem ?

Thanks

The problem for making limit work with transformItems is actually a limitation in data flow:

limit: 50 (e.g.) -> Search -> 50 facet results -> transformItems

If transformItems makes the list shorter, and we need to fetch more items, but then it would go through transformItems again. To avoid this headache of circular dependencies, we run transformItems last.

A workaround to filtering in transformItems, but still keeping limit and showMore working as if the filter worked backend, is to make your limit & showMore limit double what you would normally expect, and always calling .slice at the end of the transformItems chain. Like this:

const refinementWidget = instantsearch.widgets.refinementList({
  container: '#brand-list',
  attribute: 'brand',
  // arbitrarily big number, which you hope will still have enough results
  // tweak based on your data set
  limit: 40,
  // can not be the same as `limit`
  showMoreLimit: 41,
  showMore: true,
  transformItems(items) {
    return (
      items
        .filter(item => {
          // whatever you want to filter on.
          return item.label[0] === 'A';
        })
        // note that isShowingMore is a private variable of
        // the widget, and we do not have a public API for
        // this yet at this point.
        // also note that this will not propagate through to
        // canShowMore, since that uses the original list.
        .slice(0, refinementWidget.isShowingMore ? 20 : 10)
    );
  },
});