Infinite hits with skip and limit

I have a working code for infinite hits where it will retrieve 8 records every time I click a more button. This is done by passing hitsPerPage from redux state and calling refine() from connectInfiniteHists connector.

<InstantSearch algoliaClient={...} >
  <Configure hitsPerPage={hitsPerPage} />
<InstantSearch />

For every 8 records, it creates a section. And I need to show a banner that actually takes 2 blocks of records. The 6 records + 1 banner will also be a section. In that case, I only need to request 6 records for the first section.

If I only have 8 records and 1 banner, the first section will correctly display 6 records + 1 banner. Then when I click more button, it updates hitsPerPage to 8 as we don’t have more banner. But the problem is, it is not showing the remaining 2 records.

If I change update to hitsPerPage to 6, then it will load the remaining 2 records so that now I have 6 records + 1 banner in first section, and just 2 records in second section. But this is not a correct condition if I have 8 remaining records, it will just return 6.

What I can understand is, the hitsPerPage reacts as a limit and skip to the query. That’s why when I update it to 8, it skips the first 8 and request for the next 8 but returns empty as it thinks that we only have 8 records and we skip them all.

Is there a way to handle this situation or am I missing something?

Hi @rizky,

I’m not sure to fully understand what’s going on with what you are trying to achieve. Maybe you can reproduce it here to help us visualise: https://jsfiddle.net/vvoyer/ar80rgpc/2/

Thanks in advance!

Hi @marielaure.thuret thanks for the response, I am sorry I did not give enough visualisation to my question.

Here is pretty much what I am trying to do https://jsfiddle.net/spondbob/sm3cad75/

It shows first 6 records from the result. Then when I click load more, it shows the next 6 which total to 12 records shown. And when I click load more for second time, it should add 8 records. And so on. Instead when the hitsPerPage is changed from 6 to 8, it adds 16 records.

So I am wondering if there is any approach to make a request like “skip first 12 results and get next 8” kind of thing.

Thanks.

Hi @rizky,

Indeed there’s a bug with the connectInfiniteHits connector that doesn’t react well when you’re changing the hitsPerPage number on the fly.

I’ll open an issue on the React InstantSearch github repository and fix it.

Many thanks!

I was not sure if it was a bug or an issue with React. Hopefully will heard an update soon.
Cheers.

Hi @rizky!

Some news about your issue. It’s not really fixable at our level as changing hitsPerPage on the fly will mess with the request we are sending to the engine.

However there are some ways to perform what you want with our connectInfiniteHits connectors. I wrote a little jsfiddle showing you how to do so: https://jsfiddle.net/mthuret/mwd0fbqu/1/

Basically the idea is depending of the page you are one, deciding how many hits you should display.

Let me know how it goes while using this technique.

Hi @marielaure.thuret, thanks for the update.

That will do the trick for this moment, but with a minor issue. Instead of using hasMore to determine to show the load more button, I have to use this.props.hits.length > this.state.nbHitsDisplay. That’s because we always request for 8 records, but we don’t always show all of them. So some records are already in this.props.hits but just not shown. In that case, this.props.hits.length always higher than actual number of records shown. In some cases it is fine, but I don’t know how reliable to not using hasMore.

Would that be any workaround with the issue or is it just not possible to do so as the engine already designed as it is?

Right now I don’t have a better option for your use case. Indeed the engine is designed in a way where you ask for a given page with a given hitsPerPage. So, if on the UI side we are switching from 6 to 8 hitsPerPage, then, the page 3 for example will not be the same. Therefore you would miss some hits.

Hi @marielaure.thuret,

Sorry I have to bring this up again as the issue is happening at certain condition.

Lets say the condition is we have total of 23 records and based on the earlier case we always request for 8 but changing shown records on the client. This time, the first request will show 6 records but the next ones will show 8. It could be summarised as:

const nbHits        = this.props.hits.length
const nbHitsDisplay = this.state.nbHitsDisplay
const nbHits        = this.props.hasMore

Req   nbHits  nbHitsDisplay hasMore
1     8       6             true
2     16      14            true
3     23      22            false
4     7       30            false

The issue happens on the 4th request. As you can see nbHits only returns 7 records and remove the earlier records. I think it is similar to the issue I reported before and it may relates to the engine again.

It makes sense to make the 4th request as we only see 22 of 23 records even though hasMore says false. I have tried to not call refine() on the 4th request but it does not make any difference.

Can you have a look and see what the problem is? and if we can come up with a solution. Thanks.

Hi @rizky,

I’m not sure to understand the issue, maybe you can modify the jsfiddle that I gave you earlier to illustrate it?

If you have an hitsPerPage of 8, and your request has only 23 results, then you shouldn’t call the engine for a 4th request as there’s no results to return. To me you’re front-end implementation should just display the remaining elements when the user hit “show more”.

To me you’re front-end implementation should just display the remaining elements when the user hit “show more”.

I have tried that by not calling refine() on the 4th request where I think it should not request to server again but simply showing the remaining records. But as you can see on my table this.props.hits only has 7 records. It goes from 23 records to 7.

It is a bit difficult to show this on fiddle as the one above has more than 23 records. I am wondering if this issue may only happen at certain condition, like number of records available.

Where does those seven remaining hits came from?

Without any algorithm and code it’s really difficult to help you debug this @rizky :confused:

I don’t know. As you can see on my table, on the 3rd request I have 22 records shown, but then when I do the 4th only 7 records shown. It is very similar issue to what I have earlier in this post. The next fetching request causes previous records in this.props.hits gone.

I understand it is not easy without showing you the issue unless there is an exact dataset of 23 records to feed in the fiddle.

Hey @rizky, If you can’t share publicly an example with your data, feel free to shoot an email to support@algolia.com and I’ll try to help you with that.