InstantSearch dynamic remove/add widgets
See original GitHub issueInstantSearch::removeWidget
The goal is to be able to mount and unmount widgets from the instantSearch instance dynamically. With such a feature we would be able to build “dynamic” search experiences.
First API proposal
Every widgets are implementing a getConfiguration()
method which is indicating what SearchParameters do we need to set before querying Algolia API.
We use this method to guess which SearchParameters we need to remove from the SearchParameters when we unmount this widget.
Removing a widget also implies some DOM operations in order to remove the widget from the page. In this solution we are attaching to the widget instance a reference to the DOM node where the widget is mounted and we “automatically” remove all the content of the node.
PROS
- Non-breaking changes API
- Will work with most of the widgets already written, not a lot of code changes
CONS
- It’s not 100% safe since we are “guessing” which parameters to change after removing the widget
- If we run into issue, the code will have a lot of
if/else
branches and will become spaghetti - Can’t remove the refined value of the
NumericRefinementList
andSortBySelector
Second API proposal
In the first proposal, almost everything is done into the InstantSearch class itself. Which is great for non-breaking changes update and it should work with the widgets already implemented. But it’s also “risky” because we cannot implement a custom method for a widget behaving really differently than the others.
To avoid these potential issues, we are enhancing the connectors API. Connectors accepts a first parameters which will be the renderFn
and now they do accept a function unmountFn
which will be responsible to remove the widget from the DOM if it is requested to.
And widgets have now a new method dispose()
which takes as parameters the helper instance and the current SearchParameters / helper.state
. The dispose()
method will call the unmountFn
and return the next SearchParameters
after the widget is removed (if needed).
PROS
- Each widget is responsible for his unmount logic
- We can test each
dispose()
andunmountFn
separately
CONS
- More boilerplate code
- Semi-breaking changes in the connectors & widgets API
Conclusion
The first proposal is a sexy way to do it, because it’s “automatically” and will work most of the time and it does not require updates from the clients.
But in the end, when we will have complex cases it will become more tricky to maintain. Sometime it’s better to well separate concerns and I think here it’s the case. For instance with the first proposal there’s no easy solution to know when to remove the refined value for the NumericRefinementList
and the SortBySelector
Every own widgets should be aware of how to mount and unmount themselves: it will be easier to test and to maintain.
You can find the two PRs and the code here:
- https://github.com/algolia/instantsearch.js/pull/2374 (1st proposal)
- https://github.com/algolia/instantsearch.js/pull/2384 (2nd proposal)
Issue Analytics
- State:
- Created 6 years ago
- Comments:5 (5 by maintainers)
Top GitHub Comments
Yes this is a potential usecase, but I don’t really have something in mind for it now.
I was also thinking of a
InstantSearch::dispose
method that will remove everything from the page, when for instance the user change page on a SPA.Merged in feat/2.3 🎉