Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<Menu>/useMenu no longer functioning correctly with the new Disjunctive facet search (v0.11.0) #1007

Open
Vashiru opened this issue Feb 24, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@Vashiru
Copy link

Vashiru commented Feb 24, 2023

Description
It appears that the

element is no longer functioning correctly with the new Disjunctive facet search. This appears to be because the isRefined property is no longer properly being set. I suspect this is because it's doign multiple calls to the server to recalculate all the facets, through which the isRefined property ends up as false.

To be more specific about my scenario: I'm using useMenu of the react-instantsearch-hooks-web module to create a custom menu. I do this because I want all options to be visible at all times (not depending on what's in the results), have a 'Show all' option and to avoid the behaviour that when I click an item again, it deselects the filter.

I use the isRefined variable to see if I need to check the radio button for that particular filter.

Expected behavior
The isRefined property is properly set when you've refined that facet in your current search.

Current behavior
When picking facets using useMenu the iseRefined value remains false, unless I also pick facets in different filters. The currently refined facet also appears to disappear completely from items when there are no longer hits in the results based on the other facets in the search. This wasn't previously the case. In 0.30.0 it remained present and set as 'isRefined' because it was part of all refinements.

I've tried setting keepZeroFacets=true, this doesn't help either, it just makes items turn into an empty array all the time. It also appears the counters for useRefinementList.

Sample code:
Sample code to create a useMenu with radio buttons containing the following items:

  • All items
  • Items where ContentSubject is set to MUSIC
  • Items where ContentSubject is set to DRAMA
  • Items where ContentSubject is set to DANCE

The shouldRefine function serves 2 purposes:

  • It checks if the value you're picking to refine, is the one currently already selected, if so it does nothing to avoid deselecting the filter (which is the default behaviour of useMenu. It makes sense if you're not using radio buttons, but we want radio buttons, so that becomes an issue).
  • It avoid filtering twice in a row on "", as that triggers an error. Calling refine("") the first time resets the facet, calling it again causes an error.
function ContentSubjectFilter() {
  const { items, refine } = useMenu({
    attribute: "contentSubject",
  });

  const contentSubjects = ["MUSIC", "DANCE", "DRAMA"]; // normally they come from a databse, but I've hard coded them here for the sample

  function shouldRefine(items, valueToRefineTo) {
    console.log(items); // Here you can see that "isRefined" is no longer being set properly starting with the 2nd option you pick. 
    let isCurrentlyRefined = !!items.find((item) => item.isRefined == true);

    if (isCurrentlyRefined && valueToRefineTo === "") {
      return true;
    } else if (!isCurrentlyRefined && valueToRefineTo === "") {
      return false;
    }

    let isNewRefineValueSameAsCurrentRefinement = !!items.find((item) => {
      return item.isRefined === true && item.value === valueToRefineTo;
    });
    if (isNewRefineValueSameAsCurrentRefinement) return false;

    return true;
  }

  return (
    <ul>
      <li>
        <label
          onClick={(event) => {
            event.preventDefault();
            if (shouldRefine(items, "")) refine("");
          }}
        >
          <input
            checked={!!items.filter((item) => item.isRefined === true)}
            name={"contentSubjectRefinement"}
            type="radio"
            value={""}
            defaultChecked
          />
          Alles
        </label>
      </li>
      {contentSubjects.map((contentSubject) => {
        return (
          <li key={contentSubject}>
            <label
              onClick={(event) => {
                event.preventDefault();
                if (shouldRefine(items, contentSubject)) refine(contentSubject);
              }}
            >
              <input
                checked={
                  !!items.find(
                    (item) => item.value === contentSubject && item.isRefined
                  )
                }
                name={"contentSubjectRefinement"}
                type="radio"
                value={contentSubject}
              />
              {contentSubject}
            </label>
          </li>
        );
      })}
    </ul>
  );
}
@bidoubiwa bidoubiwa added the bug Something isn't working label Mar 1, 2023
@bidoubiwa
Copy link
Contributor

Hey @Vashiru

Thanks for the feedback! I'll look into it ASAP :)

@Vashiru
Copy link
Author

Vashiru commented Mar 30, 2023

@bidoubiwa Saw you were on holiday for a bit, but any updates on this?

@bidoubiwa
Copy link
Contributor

Hey @Vashiru
I did not have time to go deeper into this issue. It's on my list :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants