RxJS Search Input

Warning: To follow up with this article, you need some basic knowledge about Angular2, ReactiveForms, and RxJS.

Arthur Loginow
The Startup
4 min readOct 25, 2019

--

Let's pretend we are working with a Search Bar and we want to make a request to a database every time the user writes something.

We made the Search Bar using the Reactive Form Module that comes with Angular. We subscribe to our reactive form, this allows us to check the Input value every time the user types something, so far so good.

The only issue with that is that if I make a request every time the user types something, we will be dealing with dozens of unnecessary requests.

In this case, I can use one of RxJS’s operators to help me with this; that would be the DebounceTime operator (Thanks Maksym Honchar). In short, the debounceTime operator will only emit a value if a certain amount of time has passed where there were no new emitted values. In other words, it will only emit a value if the user doesn't press any key for let's say: Half of a second.

This way we are not triggering requests every time the user types something, we wait for a specified amount of time to pass before we make the request.

That’s all good, but we can still add a couple of improvements to it.

There is a catch with this approach, if the user types something, deletes it and writes that something again, we would be making a new request with a value that triggered the last request we made, so another thing that might be helpful is to make sure that we are not making a new request for a repeated value.

Here’s where the DisctinctUntilChanged operator comes to the rescue, this one, will only emit a value if the current value is different from the last emitted value. So we can implement it by chaining that operator inside .pipe() like this.

Now we are checking that the current input value is different from the last input value before making a new request with it.

This looks pretty good so far, however, I think we can improve this even further, what happens if we do not trim the white spaces at the beginning and the end of the input value?

We end up making a new request still and that is because the meaning of the value is the same, the real value is not, “this” is different from “ this ”. In this case white space matters.

Now we need to make sure that we are not considering the white spaces on the Input at the beginning and the end of the typed value, so after emitting a debounced value but before emitting a distinct value (yes, the order matters), we can check for white spaces in the emitted value, we can achieve this by squeezing a map operator between debounce and distinct:

That way we would end up with an input that waits an X amount of time before making a request, that checks that there are no white spaces at the beginning/end of the input value and after that checks, if the current value is different than the last one, something like this:

Of course, there is more behind RxJS and we could definitely improve the Search Bar beyond this point (we could implement switchMap to deal with the request every time we emit a new value from the input box), but I believe that this is enough to prove how helpful this library can be.

I really hope that this was helpful somehow to somebody, I do not consider myself an expert by any means, I am just trying to share knowledge with a community that gave me a lot so far.

I would love to make a small series about these RxJS patterns that are helpful to fulfill everyday tasks but in the meantime, I would like to know about your experiences with RxJS in the comments section.

--

--