react-instantsearch icon indicating copy to clipboard operation
react-instantsearch copied to clipboard

Range value is not cleared properly when `filters` are present

Open catamphetamine opened this issue 4 years ago • 5 comments
trafficstars

We have a timestamp attribute whose min value can be customized in the filters sidebar, and whose max value is capped programmatically using the filters property. When a user specifies some min timestamp in the UI, and then clicks "Clears All" (filters) button, the "current refinement" badge of the date attribute disappears but the searchState passed to onSearchStateChange is incorrect:

{
  configure: {
    filters: "date < 1234567890",
    distinct: true
  },
  range: {
    date: {
      min: undefined, 
      max: 1234567890
    }
  }
}

The issue is that searchState copies the max cap from the filters to the date range.

Since searchState is saved in URL, when the user refreshes the page, they see a "current refinement" badge of the date attribute as if user has set a custom value for it when in reality they have not, which confuses the user.

catamphetamine avatar Jul 30 '21 02:07 catamphetamine

Hey @catamphetamine, thanks for opening the issue.

A reproduction would help us understand what you've tried and how we can get this working. Can you please replicate the behavior in this React InstantSearch sandbox?

francoischalifour avatar Jul 30 '21 09:07 francoischalifour

@francoischalifour Hmmm, thanks. A quick demo showed that the issue was our code passing max property to the connected range widget. I don't know whether the max property should remain in state after clearing the filters though. Should it? Or should be be reset to undefined?

https://codesandbox.io/s/vigilant-lamport-dotw1?file=/src/App.js

image

catamphetamine avatar Jul 30 '21 10:07 catamphetamine

I guess it's fine. The issue in our project is specific to the project: in that project, the max property gets automatically generated on every mount (is based on Date.now()) so every time a user refreshes the page max is different. But the one that's stored in Search State URL becomes stale and shows as if a filter is selected.

For example, when max={memo(Date.now() + 1000)} and then the user specifies some filter value (slides a slider), then clicks "Clear All" — the max value in searchState is that memo(Date.now() + 1000) which gets propagated to the URL parameters, and when later the user refreshes the page, it gets read from the URL to the searchState and <InstantSearch/> thinks that the filter is "modified" when in reality it's not (it's just that its old max is less than its new max).

catamphetamine avatar Jul 30 '21 10:07 catamphetamine

If you think that's not a bug then we could close it.

catamphetamine avatar Jul 30 '21 10:07 catamphetamine

Currently, our workaround is:

    transformSearchStateForLocation (searchState) {
      // console.log('Search State:', searchState);
      // Fixes `max` start date being capped at `now + 240 days`
      // which results in it depending on the `now` timestamp (on mount):
      // if search state is written to a URL and then read from it,
      // `<InstantSearch/>` would think that the filter has been modified by the user
      // when in reality it hasn't: it's just that the new `max` is different from the old `one`.
      // https://github.com/algolia/react-instantsearch/issues/3081#issuecomment-889792436
      return {
        ...searchState,
        range: {
          ...searchState.range,
          'session.startDate': {
            ...searchState.range['session.startDate'],
            max: undefined
          }
        }
      };
    }

catamphetamine avatar Jul 30 '21 10:07 catamphetamine

Hey!

We're doing a round of clean up before migrating this repository to the new InstantSearch monorepo. This issue seems not to have generated much activity lately and to be mostly solved, so we're going to close it.

sarahdayan avatar Dec 22 '22 13:12 sarahdayan