1

Following is my scenario in which I am hitting a search API with search keyword but due to the uneven time its taking the UI is not updating correctly.

Scenario -

  1. I type a in an input box and search request goes like - search/?q=a and time its taking to resolve is 5sec.
  2. I keep on typing and now the query string is like - ab so another query goes like - search/?q=ab and assume its taking time of 4sec to get resolved.
  3. I keep on typing and now the query string is abc so another query goes like - search/?q=abc and assume its taking time to get resolved is 3sec.

So here you can see - Request 1 is getting the data in 5sec, 2 in 4 sec and 3rd in sec, so in UI the result is like -

a => /?q=a (5s)
ab => /?q=ab (4s)
abc => /?q=abc (3s)

Result in UI -

=> Result of abc
=> Result of abb
=> Result of a

But the correct order should be -

=> Result of a
=> Result of ab
=> Result of abc

My tries -

  1. I tried Promise.all. Problem is that it will update the UI only after 12 sec(5+4+3 sec).
  2. I tried Promise.allSettled() but problem is the array in which i am storing the promise is dynamic so I am not sure if this is I can enhance.

I believe this is not an edge case scenario and people might have faced it. Let me know what else I can try.

FYI - I also read about AbortController but it is clearly mentioned that its an experimental technology so I am bit hesitant in using this.

4
  • One simple way is to let your searches working in any order you want, but include the search request in the search response, and only display the response which match the current value. In your scenario, results for a and ab search will be simply ignored. Other clue is to delay your search, in order to cancel a useless call when user is typing (with debounce, which has the same support than promise). Commented Nov 25, 2019 at 19:24
  • If it is order you are looking for, you want Promise.each or async/await Commented Nov 25, 2019 at 19:25
  • Generally you keep a reference to the last request issued. When a new search comes in cancel the existing request as you do not need that response any longer. Then issue the next request. See also stackoverflow.com/a/37492399/1260204 Commented Nov 25, 2019 at 19:46
  • Possible duplicate of Promise - is it possible to force cancel a promise Commented Nov 25, 2019 at 19:47

2 Answers 2

1

there are several ways to do that at client side. the most common way I know is using debounce (from lodash)

  • using debounce, https://lodash.com/docs/4.17.15

    const loadData = (query) => {...}
    const debouncedLoadData = debounce(loadData, 200);
    
  • using setTimeout and clearTimeout.

some have lift up the concern about race and it is true. To make it perfectly then we need to implement cancellation for requests. So far, I can recommend using axios which has builting cancellation, https://github.com/axios/axios#cancellation

Sign up to request clarification or add additional context in comments.

4 Comments

What if the user waits more than 200 ms and less than 1000 ms (5s - 4s) between the 2 inputs ?
debounce is a good optimization, but it doesn't prevent race-conditions.
just find a number that works your cases :). to prevent race conditions, we need to implement a solution to cancel promise of course :)
@Piou good point, I think using axios and cancellation will ensure to fix problems
0

In react you can use hooks , Please look at this working example

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.