react-bootstrap-typeahead icon indicating copy to clipboard operation
react-bootstrap-typeahead copied to clipboard

Async search occasionally misses last letters

Open mdickin opened this issue 3 years ago • 6 comments

Version

6.0.0 (reproduced on http://ericgio.github.io/react-bootstrap-typeahead/#asynchronous-searching)

Have also seen this happen with 5.2.1

Steps to reproduce

This can be hard to reproduce, it seems to depend on typing speed. Occasionally, typing in the box will lose the last character or two. For instance (see below screenshots), typing "John" will only issue a search request for "joh".

It feels like something to do with the debounce function, but from what I've seen in the code, that's configured correctly (leading and trailing arguments aren't specified, so they default to 'false' and 'true' respectively)

Expected Behavior

The search will contain all typed in characters (after accounting for any input delay).

Actual Behavior

Results contain a few accounts that don't match "john" image

Network inspector Only one request was issued image

mdickin avatar Oct 25 '22 17:10 mdickin

@ericgio Could you please help to fix this issue. Many thanks in advance.

rg-coder avatar Nov 02 '22 16:11 rg-coder

I am facing similar issues. What seems to be happening is that the request for "joh" is fired before the request for "john", but the first one takes more time to be returned, and if the previous call is answered after the next call, it overwrites it.

nighto avatar Dec 15 '22 09:12 nighto

image

Check this example, of what I am trying to fix right now. Seems to be exactly what you are facing. You can see that this request taking longer to respond was fired before, but the actual response is after the request called after. So its contents would overwrite the contents returned by the call made after.

Of course the server not always takes this much long to answer, that's why you have it depending to typing speed.

nighto avatar Dec 15 '22 10:12 nighto

In this example, I am copy pasting the first part "72SR029001" and then typing "@6.95" at the end. I am logging on console the queried value on the onSearch function, and then the function called on promise resolution (after the values are actually fetched from backend)

image

As you can see it is not on the correct order, because the less specific query takes longer to return.

My approach / workaround to fix it is, when running the function on promise resolution, compare it with the value that is actually on the search field (i.e. typeaheadRef.current.inputNode.value) and only proceeding if they are the same.

Just for the complete reference / answer, you can get that typeaheadRef by calling const typeaheadRef = useRef(null) and then use it like <AsyncTypeahead ref={typeaheadRef} ... />.

nighto avatar Dec 15 '22 10:12 nighto

Another solution is to use AbortController to cancel any previous pending requests whenever a new one is fired.

stanleyume avatar Jan 16 '23 14:01 stanleyume

Hi @mdickin did you read this? https://github.com/ericgio/react-bootstrap-typeahead/blob/main/docs/Upgrading.md#asynctypeahead-rewritten-with-hooks

I fixed the same behavior as you are facing applying the useCallback hook as reported in the doc.

giose86 avatar Mar 13 '23 15:03 giose86

@giose86 thanks for that, I think that works for me as well! Hopefully we can get the example in the docs updated accordingly

mdickin avatar May 13 '24 16:05 mdickin