Feedback on the v2 alpha version 🆕
Not sure if this is a bug, or if I'm missing something.
I have two indexes and both of them have the same record structure. Products and Offers (not sure if I should have them on separate indexes or on the same and only have a boolean field that has isOffer for example, but that's not the point the point is, I want to display boht indexes on the same page, but when the user refine by a facet, both indexes should be synced;
Following the docs, it says: https://deploy-preview-416--vue-instantsearch.netlify.com/getting-started/migration.html#removed-options
You can now synchronize the query across indices either by using a v-model on two ais-search-boxes of which you hide one, or with ais-configure on both indices, and synchronizing between those like that.
I can sync using the query param, but not using the ais-configure;
Both indexes share the same price facet attribute, but when I apply it, it only apply to the first it and won't apply to the other.
https://codesandbox.io/s/v6nvyrko8y
v2.0.0-alpha.1
Hmm, so maybe that's documentation which is unclear, but ais-configure doesn't accept any v-model like that. It's more meant to sync for example the query or any other search parameter like done in the example.
However synchronising two widgets like that, across both indices, is something that was only added to the ais-search-box.
Do you have this in your current design requirements to synchronise a widget like price ranges across both indices?
It's interesting that you see configure as a way to synchronise both indices, it's a strategy we can explore, but would need some change.
As you can see in your demo, the query is correctly synchronised, but the prop value (which v-model implies) causes a loop of requests to appear.
Thanks for reporting your use case 😄
Haroen, thanks for your reply.
I don't need to synchronize the widgets itself, not even sure if I need to display both widgets, I just need one of them. But I need that the "filters" applied with the widgets be applied to both indexes.
This is why I thought I could use the ais-configure to sync this "search parameters"
As the facets values are added to the URL, when I reload the page, both indexes come filtered with the params that are in the URL. But only one index (the one that has the widgets) has the "live" filter.
Yes, that totally makes sense. It's something not currently foreseen in the design of the APIs, but something that we will keep in mind when we make a _proper_ way of doing multi-index.
The proper way to allow the widgets to be controlled would be like the code in SearchBox, but it's really more messy than what I'd want to build into every widget now.
A real good API would look more like the one we have in React InstantSearch, but it's not currently possible to make an abstraction like that without a bunch of caveats.
The reason the code you wrote didn't work, is because configure is meant for additional search parameters, and doesn't have info about other search parameters being used.
Doing something via routing indeed is an option, but since it's debounced, it won't be as live as it should be, as well as probably clash with each other.
Right now this more advanced multi index search isn't a finished story yet I think. It's likely something for a next iteration of Vue InstantSearch instead, but it's definitely useful to see the need for the feature. If anyone else reads this issue later and it's not been finished yet, please upvote the original issue.
Does anybody know if there are any solutions yet in relation to this?
I have a use case where I want to expose the current refinements from one ais-instant-search instance and pass to another.
I have routing in place and had hoped that routeToState would take affect across all ais-instant-search instances if the same routing object is passed to the routing prop of every instance
@resao We don't have a proper API yet to do multi-index with Vue InstantSearch but it's something that we want to provide at some point. In the meantime, with the routing we can probably manage to hack a workaround. A live example of what you already tried would help to better understand your use case though.
The routeState takes effect but only on the initial render and popstate event. We can't subscribe for pushstate event that's why it's not triggered. We can monkey patch the router though to access the function that runs on popstate event.
import { history } from "instantsearch.js/es/lib/routers";
let updateSubRouter = () => {}
const mainRouter = history();
const subRouter = history();
const mainRouterWrite = mainRouter.write.bind(mainRouter);
mainRouter.write = routeState => {
// push changes on the sub instance
updateSubRouter(routeState);
// call the original function
mainRouterWrite(routeState);
};
const subRouterOnUpdate = subRouter.onUpdate.bind(subRouter);
subRouter.onUpdate = callback => {
// callback to update the sub instance
updateSubRouter = callback;
// call the original function
subRouterOnUpdate(callback);
};
// avoid the sub router to write the URL
subRouter.write = () => {};
It depends on your use case but it might help. Here is an example that shows how to apply this logic to Vue InstantSearch to share searchBox & refinementList across two different instances. The first instance drives the second one, every refinement applied to the "main" one are applied to the other.
An important thing to notice is that the widget remains mounted on the second instance (but hidden). We can go further than just hide them, we could render them headless but I didn't do it in the example to keep it simple. The fact that the widgets have to be mounted is a requirement of Vue InstantSearch. Otherwise, the refinements are not applied on the request.
Thanks @samouss
That looks like a good solution as it ensures that the relationship and router updates are one-way i.e. main → sub
I'll give that a go!
Cheers
@samouss
Your solution has worked perfectly.
I am also successfully using it alongside user-friendly urls
Thanks for your help!!
This is solved with the ais-index component and routing added in v3 👍
Most helpful comment
@resao We don't have a proper API yet to do multi-index with Vue InstantSearch but it's something that we want to provide at some point. In the meantime, with the
routingwe can probably manage to hack a workaround. A live example of what you already tried would help to better understand your use case though.The
routeStatetakes effect but only on the initial render andpopstateevent. We can't subscribe forpushstateevent that's why it's not triggered. We can monkey patch therouterthough to access the function that runs onpopstateevent.It depends on your use case but it might help. Here is an example that shows how to apply this logic to Vue InstantSearch to share
searchBox&refinementListacross two different instances. The first instance drives the second one, every refinement applied to the "main" one are applied to the other.An important thing to notice is that the widget remains mounted on the second instance (but hidden). We can go further than just hide them, we could render them headless but I didn't do it in the example to keep it simple. The fact that the widgets have to be mounted is a requirement of Vue InstantSearch. Otherwise, the refinements are not applied on the request.