• author: Coding in Public

Enhancing the Search Functionality on Our Website

In the previous lessons of this series, we have made significant progress in building our website's search feature. We've added a form on the homepage for users to enter their queries, and with a simple press of the enter key, they are directed to the search route where the search results are displayed. Last time, we even created a JSON file called search.json that stores all the content from our posts, enabling us to populate our search results page with relevant information.

But now, it's time to take it one step further. We want to optimize the search functionality by loading the search data directly onto the client's browser. Whether the user types in the search term or lands on the search results page, we want to retrieve the data and store it on the browser, reducing the need to fetch it repeatedly.

To achieve this, we'll implement a mechanism to check if the data has already been fetched before making subsequent requests. Let's dive into the code and see how we can accomplish this.

Checking if the Data is Already Fetched

The first thing we need to do is define a variable to hold our search data. We'll call it searchData and mark it as a static variable by capitalizing the first letter. This signifies that the data should not change once fetched. We'll use this variable to store the search data and update it only when we update our website statically.


Now, let's create a function called fetchSearchResults to handle the process of fetching the search data and processing the results. This function will fetch our search.json file and retrieve the data from it. We'll also log the retrieved data for debugging purposes.


To test this function, we can call it in the browser's console. For example, if we type fetchSearchResults() and press enter, we should see all five search results logged to the console.

However, it's always a good practice to handle errors and ensure the network request is successful. We can improve our error handling by checking if the response from the network request is ok. If it's not, we can throw a new error and display a message to the user.

try{if(!res.ok){thrownewError('Something went wrong. Please try again.');}// process the data here}catch(error){console.error(error);}

Now, if we mistype the URL or encounter any other error, we'll receive an error message indicating that something went wrong.

Updating the Search Data

Our next task is to update the searchData variable with the fetched data if it doesn't already exist. We'll modify our code to only perform the fetch request if the searchData variable is empty. This way, we won't fetch the data repeatedly.

To achieve this, we'll check if searchData is falsy (meaning it's either null, undefined, or an empty string) and perform the fetching process only if it is. Within the fetch function, we'll update the searchData variable with the retrieved data.


Now, when we type a search term or land on the search results page, the data will be fetched only if searchData is empty. Once fetched, it will be stored in the searchData variable.

Optimizing Search Functionality

While the data is being fetched and processed, we want to provide feedback to the user by displaying a spinner. To achieve this, we'll create a spinner HTML element using an SVG image. We'll add a spinning animation to the SVG to indicate that the request is being processed.

<svgxmlns="http://www.w3.org/2000/svg"viewBox="0 0 24 24"><style>@keyframesspin{100%{transform:rotate(360deg);}}#spinner{animation:spin1slinearinfinite;}</style><pathid="spinner"fill="currentColor"d="M8 0L4 4l4 4L0 12l8 8 8-8-4-4 4-4z"/></svg>

We'll add an ID to the search-results container where the search results will be displayed. This will allow us to dynamically update its content.


To implement the spinner functionality, we'll update the fetchSearchResults function. Firstly, we'll grab the search-results container and store it in a variable. Then, while the data is being fetched and processed, we'll set the innerHTML of the container to display the spinner.

asyncfunctionfetchSearchResults(){constsearchResultsContainer=document.getElementById('search-results');try{if(!searchData){searchResultsContainer.innerHTML='<div class="spinner">...</div>';constres=awaitfetch('search.json');constdata=awaitres.json();searchData=data;// Process the search results here and update the search results container with the relevant content}}catch(error){console.error(error);}}

Now, when the search results are being fetched, the search-results container will display a spinner instead of the actual content. Once the data is processed, we can update the container with the relevant search results.

Improving Performance by Skipping Unnecessary Requests

We don't want to make unnecessary fetch requests every time a user types a new character in the search input field. To prevent this, we'll modify our code to check if a search term exists before fetching the data. If the search term length is zero, we'll skip the fetch request altogether.


This modification ensures that data is fetched only when there is a valid search term and the data hasn't been fetched previously.


In this lesson, we have enhanced the search functionality on our website by optimizing the data retrieval and updating process. We have implemented a mechanism to check if the data has already been fetched and to prevent unnecessary fetch requests. Additionally, we have provided visual feedback to the user by displaying a spinner while the data is being fetched. These improvements help improve the performance and user experience of our search feature.

In the next lesson, we will explore a lightweight fuzzy search library called Fuse.js. This library will allow us to perform more advanced search queries based on the user's input. Stay tuned for Lesson Seven!

Previous Post

How to Update Search Results and URL in a Web Application

Next Post

How to Use the Fuse.js Library for Client-Side Processing

About The auther

New Posts

Popular Post