Creating a Search Field

**This blog post is just one part of a series of Angular tutorials & advanced topics. Make sure you take a look!

Creating a Search Field

When we need to create a search field in a form using the Angular framework or any, we should ask ourselves some basic questions:

  1. What should be triggered once the user types? do we validate the input of the chars one by one?
  2. Should the user finish typing, then hit a search button? or should the results be rendered every keystroke seamlessly?

These are important questions that one should ask, they will affect the entire user experience. For example, when you type a search field in GOOGLE it immediately shows your results. But from the backend perspective, it is a bad practice to invoke a search query on the database on every char a user hits, there can be many mistakes as he types and you can never know if this search is really what he means or is he currently still typing, so the last request you sent to the server is not needed anymore and if you just waited a few seconds the search input would be so much more understandable and closer to what the user actually intended.

What we should do is use the debounce method and wait a few milliseconds, then understand if there are still more chars coming our way and if it’s safe and effective to start the search on the backend side. This way we are saving many non-relevant round trips to the server and reducing the load.

Rxjs DebounceTime

Angular has a different approach using the RXJS library.

Let`s start implementing it in Angular. we will start by adding a “keyup” event to our HTML template such as:

<input type="text" (keyup)="onSearchType($event.target.value)"/>

We use the “keyup” event and send the $event input- a regular javascript event that happens as keys are released in the keyboard.  The target parm gives the input which initiated the event, the value parm is currently the value in the text field.

What we are trying to achieve is that for every keypress, we will wait a few ms and examine what happens, if the user stops we will send the current value as the search input – else we will keep on waiting until he seems to stop typing…

To achieve this we will use Subject class, The Subject class inherits both Observable and Observer, so it is actually a proxy class that can subscribe or emits messages. it can also resend what it was subscribed to,  It is basically of the pub-sub design pattern.

import{Subject} from "rxjs";
....
/// Now create a private member called searchUpdated of type Subject:

private searchUpdated: Subject = new Subject();

In the Component add a function that listens to the key event


private onSearchType(value: string) {
    console.log(value);
    this.searchUpdated.next(value); 
// Emit the event to all listeners
 // that have subscribed - we will subscribe in our contractor

}

We are just emitting the given value again to whoever is subscribed. Next, we will create an Output field so anyone can subscribe to our event from outside of the component,


import{Subject,debounceTime,distinctUntilChanged} from "rxjs";
....

@Output() searchChangeEmitter: EventEmitter = new EventEmitter();  // // This is an output component that tells the rest of the world that // the user has entered a valid text
constructor() 
    this.searchChangeEmitter = this.searchUpdate.asObservable()
        .pipe(debounceTime(200),
              distinctUntilChanged());// accept only relevant chars
}

We will notice we are using “asObservable” to make it a fireable observable, we will wait a few milliseconds (200 seems enough) to see if there are any other keys that are still to come then we can broadcast outside of our component (@Output) using the EventEmitter that has the @Output decorator.

One Important comment – make sure to unsubscribe from the search subject once the component is in the OnDestroy cycle. The “takeUntil” is a great way to achieve this goal.

To summarise: we created a search field in our component that anyone can subscribe to from outside only if the input has changed in a meaningful way, without damaging the user experience and without overloading the server eventually.

**This blog post is just one part of a series of Angular tutorials & advanced topics. Make sure you take a look!

Angular – Creating a search field with debounce time

Also published on Medium.

Yoni Amishav


Tech lead, blogger, node js Angular and more ...


Post navigation


4 thoughts on “Angular – Creating a search field with debounce time

  1. Will your Subject “searchUpdate”not be overridden by your output “searchUpdate”. You should really name them differently to avoid confusion as I personally, as a new user of Angular2, cannot follow this example because of this. which “searchUpdate” is being referenced in the “onSearchType” and which is being referenced in the constructor?

  2. Hi, thanks for you valuable advise, I updated the post hopefully now its clearer,There are 2 aspects of the component , one is an inside listener and the other one emit outside the component. When a user types it is handled by our component function onSearchType, then the Subject passes is to all registered listeners, In our constructor we register our EventEmitter to the listen and fire only if 200 ms has passed and the data is valuable. Please let me know if its clearer

Leave a Reply

Free Email Updates
Get the latest content first.
We respect your privacy.
%d