Instantsearch JS - results from one category with custom hits

I’m facing one issue. I have a custom search with Instantsearch.js and for it I’m having custom results because I wanted to skip default hits with extra divs [I’m doing a carousel based on it]

Right now I’m facing two issues.

First issue:
How can I generate default results based on a one category. At this point default view should show only elements from one category, when user search for more it should search only within this category.

I have attribute named: category and it has some values like categoryname1, categoryname2, categoryname3

I tried using:
options.helper.addFacetRefinement but it’s been throwing error that:
" category is not defined in the facets attribute of the helper configuration

Can someone point me what is the best way to solve that and get results only from one category?
Looks like i’m missing something from facets. I’m not using any custom checkboxes for users, they don’t need to control that.

Second issue:
When building carousel I’m just using simple vanilla js to move everything based on div’s and setting for them data-target attribute, count number of elements and move everything.
This works perfectly but not with Algolia generated search elements.

I tried to wait some time before calling carousel, until elements will be loaded with setTimeout but the same results.

What I am missing in there?

Thanks in advance

//Edit:

I took different approach and so far I’m close with solving it.

For the first question, you can also look into initialUiState or routing (a parameter to the constructor) if the widget is mounted, or configure if the filter isn’t shown to the user.

For the second, a connectHits likely fits your use case well, but I’m not fully sure how you use your carousel, so I’d need to see a code sample to see if it fits as expected.

1 Like

Hi Haroen,
Sorry for my late message and thanks for advice.
I solved most of that.

One issue I’m facing is getting no results to work with my code.

I have custom hits, creates custom widget and initiate it. But in default can not get “no results message” if there is no results to query that doesn’t exist.

Is there a way to make that happen?

My code looks like that:

const renderHits = (renderOptions, isFirstRender) => {
    const { hits, widgetParams } = renderOptions;

    widgetParams.container.innerHTML = `
    
      ${hits
            .map(
                item => `<div class="item" data-target="card">
            <a href="${item.linkURL}"><img src="${item.imageURL}"/>          
              <strong>${item.name}</strong>
              </a>
</div>`
            )
            .join('')}
    
  `;
};

const customHits = instantsearch.connectors.connectHits(renderHits);

search.addWidgets([
    customHits({
        container: document.querySelector('#hits'),
    })
]);

Could you point me what I’m missing? For example in React everything is in default but for this one I’m using Instantsearch.js

I’m not sure I fully get what the problem is; is it possible to reproduce in a sandbox? We have one available here: http://codesandbox.io/s/github/algolia/create-instantsearch-app/tree/templates/instantsearch.js

Actually it isn’t possible to reproduce in sandbox because this one uses template and I’m using custom hits.

I found this solution:

How to handle empty queries using helper state or connector.
In my use case I used connector but still don’t get it.
I can get my all results but no results message doesn’t show. Looks like issue with connector and renderHits method.

I will create some quick sandbox with my code and update this post. This should tell you more about issue I’m facing.

I added everything in here:

It isn’t nice one but shows that no results doesn’t work. Everything within main.html file.

Any idea what I can do to make it work with custom hits?

I’m not sure I understand what you mean; but you can add a conditional in the content for hits: https://codesandbox.io/s/intelligent-sid-0euhg?file=/index.html

I also think that the code you have in a render event would work better if it was part of the body of the custom hits component, although I’m not sure what it’s exactly supposed to do

Hope this helps already anyway!

1 Like

That was amazing.
Thank you for your help Haroen. Thank for advice about render event. I’m changing this one.

Just one more if can I ask.
Is it possible with instantsearch.js achieve config that will allow to place the same code in 2 different places but display results from different categories?

My code is a carousel and display results with searchParameters based on FacetsRefinements.
I want to use everything the same but put carousel in another page with the same search and custom hits but serve from different category.

What would be better way to do that. I’ve been thinking on creating different widgets with different search and customHits containers for that and make something similar to how multiple indices are controlled with InstantSearch. Or maybe there will be other, simple way of doing that?

Do you have a drawing or diagram of what you want to achieve? You can look at the index widget maybe? https://www.algolia.com/doc/api-reference/widgets/index-widget/js/

You could also make your custom hits widget accept a parameter that you read in the rendering:

const customHits = connectHits((renderArgs, isFirstRender) => {
  const { widgetParams } = renderArgs;
  const { name, someOtherArgument } = widgetParams;
});

search.addWidgets([
  customHits({
    name: 'myName',
    someOtherArgument: true,
  }),
]);
1 Like

Thank you for piece of advice.

I don’t have any specific diagram but I have 3x separate pages on which you can find different type of content.

I want to display section with this results:

But need to display it from different category for each page.
For example On page: Shoes want section that will be displaying results from ‘category1’ and section Boots display from ‘category2’

Right now my code can display results and search within this one category based on Search Parameter and disjunctiveFacetsRefinements where I set a category: [“category2”],

But I’m looking how achieve best way of doing that and displaying search and results that will reflect a page you’re on at this moment.
I tried setting widget with different container for custom hits and search parameter but looks like search parameters and facets are not supported with this use case?
Or there is a different way to achieve that.

your sandbox is kinda confusing, sorry! but if you want different sets of hits with different parameters, you can look at the index widget:

search.addWidgets([
  index({ indexName: 'myIndex', indexId: 1 }).addWidgets([
    configure({ ...specialParametersFor1 }),
    customHits(),
  ]),
  index({ indexName: 'myIndex', indexId: 2 }).addWidgets([
    configure({ ...specialParametersFor2 }),
    customHits(),
  ]),
]);
1 Like

Thank you.
I’ll try that.
Not quite sure if it will fully work with my example because so far been getting errors due to index. But hope it will be ok.

Can I ask what is kinda confusing in a sandbox? This is the sandbox you copied form my earlier one.

I generate custom hits to make different style and have extra code for a carousel but that one doesn’t fully work in sandbox. I can fix it so you can take a look at that closer.

I wanted to display search results from the same index but depends on a page you’re visiting [category page] display results within carousel from different category. This is why I have searchparameter at top:

searchParameters: {
hitsPerPage: 24,
disjunctiveFacetsRefinements: {
category: [“Mug”],
}
}