At XpresServers, we constantly strive to deliver total customer satisfaction with all our hosting services. That’s why we offer fast, reliable and secure service that’s backed by our friendly, knowledgeable support team, 24/7.

Bar

The author selected Mozilla Foundation to receive a donation as part of the Write for DOnations program.

Introduction

Reactive Programming is a paradigm concerned with asynchronous data streams, in which the programming model considers everything to be a stream of data spread over time. This includes keystrokes, HTTP requests, files to be printed, and even elements of an array, which can be considered to be timed over very small intervals. This makes it a perfect fit for JavaScript as asynchronous data is common in the language.

RxJS is a popular library for reactive programming in JavaScript. ReactiveX, the umbrella under which RxJS lies, has its extensions in many other languages like Java, Python, C++, Swift, and Dart. RxJS is also widely used by libraries like Angular and React.

RxJS’s implementation is based on chained functions that are aware and capable of handling data over a range of time. This means that one could implement virtually every aspect of RxJS with nothing more than functions that receive a list of arguments and callbacks, and then execute them when signaled to do so. The community around RxJS has done this heavy lifting, and the result is an API that you can directly use in any application to write clean and maintainable code.

In this tutorial, you will use RxJS to build a feature-rich search bar that returns real-time results to users. You will also use HTML and CSS to format the search bar. The end result will look this this:

Something as common and seemingly simple as a search bar needs to have various checks in place. This tutorial will show you how RxJS can turn a fairly complex set of requirements into code that is manageable and easy to understand.

Prerequisites

Before you begin this tutorial you’ll need the following:

The full code for the tutorial is available on Github.

Step 1 — Creating and Styling Your Search Bar

In this step, you will create and style the search bar with HTML and CSS. The code will use a few common elements from Bootstrap to speed up the process of structuring and styling the page so you can focus on adding custom elements. Bootstrap is a CSS framework that contains templates for common elements like typography, forms, buttons, navigation, grids, and other interface components. Your application will also use Animate.css to add animation to the search bar.

You will start start by creating a file named search-bar.html with nano or your favorite text editor:

Next, create the basic structure for your application. Add the following HTML to the new file:

This uses the grid system from Bootstrap to structure the page header and the search bar. You have assigned a search-input identifier to the search bar, which you will use to bind to a listener later in the tutorial.

Next, you will create a location to display the results of the search. Under the Results comment, create a div with the response-list identifier to add the results later in the tutorial:

In this step, you've laid out the basic structure for your search bar with HTML and CSS. In the next step, you will write a JavaScript function that will accept search terms and return results.

Step 2 — Writing the JavaScript

Now that you have the search bar formatted, you are ready to write the JavaScript code that will act as a foundation for the RxJS code that you'll write later in this tutorial. This code will work with RxJS to accept search terms and return results.

Since you won't need the functionalities that Bootstrap and JavaScript provide in this tutorial, you aren't going to load them. However, you will be using RxJS. Load the RxJS library by adding the following under the Load RxJS comment:

Next, add the code to convert the JSON response from the API into the HTML elements to display on the page. This code will first clear the contents of the search bar and then set a delay for the search result animation.

The code block starting with if is a conditional loop that checks for search results, and displays a message if no results were found. If results are found, then the forEach loop will provide the results with an animation to the user.

In this step, you laid out the base for the RxJS by writing out a function that can accept results and return it on the page. In the next step, you will make the search bar functional.

Step 3 — Setting Up a Listener

RxJS is concerned with data streams, which in this project is a series of characters that the user enters in to the input element, or search bar. In this step, you will add a listener on the input element to listen for updates.

First, take note of the search-input identifier that you added earlier in the tutorial:

Next, create a variable that will hold references for the search-input element. This will become the Observable that the code will use to listen for input events. Observables are a collection of future values or events that an Observer listens to, and are also known as callback functions.

Add the highlighted line in the <script> tag under the JavaScript from the previous step:

Now that you've added a variable to reference input, you will use the fromEvent operator to listen for events. This will add a listener on a DOM, or Document Object Model, element for a certain kind of event. A DOM element could be a html, body, div, or img element on a page. In this case, your DOM element is the search bar.

Add the following highlighted line under your searchInput variable to pass your parameters to fromEvent. Your searchInput DOM element is the first parameter. This is followed by the input event as the second parameter, which is the event type the code will listen for.

Now that your listener is set up, your code will receive a notification whenever any updates take place on the input element. In the next step you will use operators to take action on such events.

Step 4 — Adding Operators

Operators are pure functions with one task—to perform an operation on data. In this step, you will use operators to perform various tasks such as buffering the input parameter, making HTTP requests, and filtering results.

You will first make sure that the results update in real-time as the user enters queries. To achieve this, you will use the DOM input event from the previous step. The DOM input event contains various details, but for this tutorial you are interested in values typed into the target element. Add the following code to use the pluck operator to take an object and return the value at the specified key:

Now that the events are in the necessary format, you will set the search-term minimum to three characters. In many cases, anything less than three characters will not yield relevant results, or the user may still be in the process of typing.

You will use the filter operator to set the minimum. It will pass the data further down the stream if it satisfies the specified condition. Set the length condition to greater than 2 to require at least three characters.

You will also make sure that requests are only sent in at 500ms intervals to ease up the load on the API server. To do this, you will use the debounceTime operator to maintain a minimum specified interval between each event that it passes through the stream. Add the highlighted code under the filter operator:

The application should also ignore the search term if there have been no changes since the last API call. This will optimize the application by further reducing the number of sent API calls.

As an example, a user may type super cars, delete the last character (making the term super car), and then add the deleted character back to revert the term back to super cars. As a result, the term did not change, and therefore the search results should not change. In such cases it makes sense to not perform any operations.

You will use the distinctUntilChanged operator to configure this. This operator remembers the previous data that was passed through the stream and passes another only if it is different.

Now that you have regulated the inputs from the user, you will add the code that will query the API with the search term. To do this, you will use the RxJS implementation of AJAX. AJAX makes API calls asynchronously in the background on a loaded page. AJAX will allow you to avoid reloading the page with results for new search terms and also update the results on the page by fetching the data from the server.

Next, add the code to use switchMap to chain AJAX to your application. You will also use map to map the input to an output. This code will apply the function passed to it to every item emitted by an Observable.

status: The HTTP status code returned by the API server. This code will only accept 200, or successful, responses.

details: The actual response data received. This will contain the results for the queried search term.

result_hash: A hash value of the responses returned by the API server, which for the purpose of this tutorial is a UNIX time-stamp. This is a hash of results that changes when the results change. The unique hash value will allow the application to determine if the results have changed and should be updated.

Systems fail and your code should be prepared to handle errors. To handle errors that may happen in the API call, use the filter operator to only accept successful responses:

Next, you will add code to only update the DOM if changes are detected in the response. DOM updates can be a resource-heavy operation, so reducing the number of updates will have a positive impact on the application. Since the result_hash will only change when a response changes, you will use it to implement this functionality.

To do this, use the distinctUntilChanged operator like before. The code will use it to only accept user input when the key has changed.

You previously used the distinctUntilChanged operator to see if the entirety of the data had changed, but in this instance, you check for an updated key in the response. Comparing the entire response would be resource-costly when compared to identifying changes in a single key. Since the key hash is representative of the whole response, it can confidently be used to identify response changes.

The function accepts two objects, the previous value that it had seen and the new value. We check the hash from these two objects and return True when these two values match, in which case the data is filtered out and not passed further in the pipeline.

In this step, you created a pipeline that receives a search term entered by the user and then performs various checks on it. After the checks are complete, it makes an API call and returns the response in a format that displays results back to the user. You optimized the resource usage on both the client and server side by limiting API calls when necessary. In the next step, you will configure the application to start listening on the input element, and pass the results to the function that will render it on the page.

Step 5 — Activating Everything with a Subscription

subscribe is the final operator of the link that enables the observer to see data events emitted by the Observable. It implements the following three methods:

onNext: This specifies what to do when an event is received.

onError: This is responsible for handling errors. Calls to onNext and onCompleted will not be made once this method is called.

onCompleted: This method is called when onNext has been called for the final time. There would be no more data that will be passed in the pipeline.

This signature of a subscriber is what enables one to achieve lazy execution, which is the ability to define an Observable pipeline and set it in motion only when you subscribe to it. You won't use this example in your code, but the following shows you how an Observable can be subscribed to:

Next, subscribe to the Observable and route the data to the method that is responsible for rendering it in the UI.

Now that you've completed writing the code, you are ready to view and test your search bar. Double-click the search-bar.html file to open it in your web browser. If the code was entered in correctly, you will see your search bar.

Type content in your search bar to test it out.

In this step, you subscribed to the Observable to activate your code. You now have a stylized and functioning search bar application.

Conclusion

In this tutorial, you created a feature-rich search bar with RxJS, CSS, and HTML that provides real-time results to users. The search bar requires a minimum of three characters, updates automatically, and is optimized for both the client and the API server.

What could be considered a complex set of requirements was created with 18 lines of RxJS code. The code is not only reader-friendly, but it is also much cleaner than a standalone JavaScript implementation. This means that your code will be easier to understand, update, and maintain in the future.

To read more about using RxJS, check out the official API documentation.