search-ui icon indicating copy to clipboard operation
search-ui copied to clipboard

Allow to set replaceUrl option when calling actions (eg. setFilter)

Open marcvangend opened this issue 3 years ago • 13 comments

In #449 a replaceUrl option was added to the pushStateToURL method. I would like to be able to set that option when calling an action that changes the state of the search context.

My use case: My app has a route /product/:id which shows information about a product. One of the components on the page is a Search UI component with search results filtered by the ID of the product. Using withSearch, I can get the setFilter action from the context and implement a useEffect hook to set the filter when the route is loaded:

useEffect(() => {
  setFilter('product', getCurrentId());
});

Now when a visitor navigates to the product page and then goes back in the browser history, they will remain on the product page because the setFilter call has pushed a new URL onto the history stack. This could be solved if I were able to set the replaceUrl option when calling setFilter (eg. setFilter('product', getCurrentId(), { replaceUrl: true });)

If you think my approach is completely wrong, feel free to let me know :-)

marcvangend avatar Mar 30 '21 12:03 marcvangend

Oh, in this case, could you just disable trackUrlState for the product detail page? Seems like you don't really need url state: https://github.com/elastic/search-ui/blob/master/ADVANCED.md#advanced-configuration

JasonStoltz avatar Mar 30 '21 12:03 JasonStoltz

Thanks @JasonStoltz. I did consider that, but the search component on the product page exposes a couple of additional filters, so I'd like to track those in the URL state.

That said, your comment got me thinking: maybe it would work if I disable trackUrlState before I call setFilter and immediately enable it again? I'll give that a try, but it does sound like a hack rather than intended usage.

marcvangend avatar Mar 30 '21 16:03 marcvangend

@marcvangend OK, then I have another idea for you.... try a "Global Filter": https://github.com/elastic/search-ui/blob/master/ADVANCED.md#global-filters

This is something you'll configure directly on the SearchProvider. It will be transparent in the URL and applied to every query.

JasonStoltz avatar Mar 31 '21 12:03 JasonStoltz

@JasonStoltz so you're saying I could dynamically change this global filter based on the ID I get from the route? Interesting, I didn't think of that. I suppose that can only happen in the component where I embed <SearchProvider>, right? I mean, this configuration is not mutable from underlying components through the withSearch context - or am I wrong?

marcvangend avatar Mar 31 '21 14:03 marcvangend

Yes, that sounds correct.

JasonStoltz avatar Apr 01 '21 12:04 JasonStoltz

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Is this issue still important to you? If so, please leave a comment and let us know. As always, thank you for your contributions.

botelastic[bot] avatar May 31 '21 12:05 botelastic[bot]

Thanks for reminding me, Bot. I was not able to get this working with the provided suggestions. As far as I'm concerned, the original request would still be a better solution (both for my situation and in terms of library architecture) than fiddling with global state.

marcvangend avatar May 31 '21 13:05 marcvangend

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Is this issue still important to you? If so, please leave a comment and let us know. As always, thank you for your contributions.

botelastic[bot] avatar Jul 30 '21 13:07 botelastic[bot]

Yes, this is still relevant to me, and yes, I still think the proposed solution is superior to the workaround.

marcvangend avatar Jul 30 '21 14:07 marcvangend

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Is this issue still important to you? If so, please leave a comment and let us know. As always, thank you for your contributions.

botelastic[bot] avatar Sep 28 '21 15:09 botelastic[bot]

Just re-reading this issue. For what it's worth, I still don't understand why you can't use the Global Filters (aka Base Filters) approach.

https://docs.elastic.co/search-ui/api/core/configuration#filters-global-filters

  1. User navigates to http://www.example.com/product/12345
  2. Read the ID from the URL, and set it as a base filter on the page when configuring Search UI:
const configurationOptions = {
  apiConnector: connector,
  searchQuery: {
    filters: [{ field: "product", values: ["12345"] }],
  },
  alwaysSearchOnInitialLoad: true,
};

That will load the page with the product filter applied. The product id will not be tracked in the URL because it is applied as a base filter. You will have no issue with the back button either. All other search parameters will be tracked in the URL.

JasonStoltz avatar Jul 08 '22 16:07 JasonStoltz

Sorry for this seriously delayed response, we are thinking about a new approach from URL state currently.

JasonStoltz avatar Jul 08 '22 16:07 JasonStoltz

This effort may help as well: https://github.com/elastic/search-ui/issues/790

JasonStoltz avatar Jul 08 '22 17:07 JasonStoltz