# A generalized debounce/search problem

# The UI problem

We have a login form where username needs to be unique.

When you type the username, we make a request using `validateUsername(username: string): Promise<boolean>`.

With the result of the request, we update the helper text below the input to either show that the username is available or not. We use the function `updateLabel(text: string)`.

The request can not be made on every keystroke. Otherwise, we'd overload the server.

`inputUpdated(text: string)` is called on every keystroke.

Now, for this problem, assume debounce is a generalized function. It debounces every single call.

# The very naive solution

To show you some pseduo code, we solve this problem by using debounce.

```js
function inputUpdated(text: string) {
  debounce(() => {
    // ...
  });
}
```

The problem with this solution is for every keystroke, we create a new debounce.

We could solve this by clearing the previous debounce e.g. if we're giving an id or something. In JavaScript, we could use `clearTimeout` which would be implemented inside the debounce function.

We still have one problem. What if the user types "ab", waits a bit and then types "abc"?

"ab" may not be available, so with the response we update the label to say it is not available. Even though "abc" is available which is what the user sees.

# A potential solution

One solution is to abort the previous request. This works if the request is in-flight. But if we already have the response, we can't abort it...

By the way, in JavaScript, you would use `AbortController` to abort a request.

# The solution

We can create a dictionary where we map the user's input (a username) to the result.

Going back to the issue we had where "ab" is not available, but "abc" is, in this case we would look at the dictionary e.g. a Map and see that "abc" is not in there, therefore we can be sure to NOT update the label.

It's better to wait for the right result then to show the user the wrong result.

In the end, we'd have:

abc -&gt; true ab -&gt; false

With `abc` being in the Map, we know to update the label.

Well, when I think about it, we can always update the label but we decide whether to show it or not based on the Map.
