7 days of unlimited WordPress themes, plugins & graphics - for free!* Unlimited asset downloads! Start 7-Day Free Trial
  1. Web Design
  2. APIs

Build a Recipe Search Tool Using Javascript and TheMealDB API

Scroll to top
Read Time: 10 mins

Finding new recipes can be an exciting change of pace from the typical meals you might prepare in your household.If you are like me, you tend to have a simple set of ingredients and often need inspiration to come up with something new to prepare. This tutorial solves that problem by building a recipe search tool using the open-source MealDB API.

What We Will be Building

The core example of this tutorial is to build a search form that we can use to filter meal ideas. All search results will return from theMealDB API, and I invite you to extend this as far as you feel worthy. The API provides many endpoints to make use of should you desire.

our recipe search engine uiour recipe search engine uiour recipe search engine ui

HTML Recipe Template from Envato Elements

For this tutorial, I’ll be making use of an HTML recipe template titled Cook Note - Food Recipes HTML Template found on Envato Elements. Get unlimited downloads with a single subscription!

the recipe html template we’ll be usingthe recipe html template we’ll be usingthe recipe html template we’ll be using

If you’d rather use a different template, or your own HTML markup, you can still easily follow this tutorial.

Setting up the Project

To appropriately target and display results in the theme, we need access to a few HTML elements on the search-page.html template from the bundle. I’ll modify the search form and the page’s contents to be dynamic based on a user’s search query.

Create a file called search.js and add it to the assets/js folder if you follow along with the template.

HTML Markup

In the HTML markup, I modified the existing code on the form by removing the category dropdown and making the search field wider. A category dropdown is a helpful feature, but we won’t use the more advanced search tactics in this tutorial.

Inside the template, the form submit button was previously an anchor link, so I switched this back to a button HTML tag so the form will submit successfully once clicked.

On the form element, add an id attribute called search-form. This ID will be how we target the form and manipulate the page once it submits.

Displaying the Results

The main content of the page will be a list of meals that displays upon successful search. We can add a placeholder message for now wrapped in a containing div element with the id of search-results. We’ll dynamically use JavaScript to add elements to the page within this container.

The JavaScript

I’ll take a class-based approach to kick things off with the JavaScript logic. This direction aims to make the entire JavaScript class a re-usable instance that could be used on different pages if necessary.

I won’t go into detail about how classes work in JavaScript, but the core idea is that it relates to object-oriented programming patterns. Languages like Ruby, PHP, and more use these principles often.

Let’s first create a new class I’ll call Search.

The class can accept arguments which ultimately give it the reusability features I mentioned before.

I’ll create an instance of the form element in the HTML markup.

Before doing so, I’ll listen for the DOMContentLoaded event, which means the HTML page must load first before performing any code inside the body of the function.

Notice how the Search class remains outside of the document.addEventListener function. I made this decision intentionally as we can reference the class from within the other function thanks to the global scope.

The initialize function is one I created to put our logic to work. Typically, you need to assign a new class instance to a variable and only then call methods on it.

The constructor function forms an argument and lets us assign it to a new instance on the Search class. This configuration gives us a top-level way to access the form consistently.

I added one more instance to the search-results div we added in the HTML a few steps back. Again this gives us an easy reference to the results as we’ll need it coming up.

In the code example above, the output of the initialize() function should return the form element within your browser’s console log.

Search on Form Submission

We’ll listen for the form’s submit event to perform a search, which requires the event listener method we used before. Inside the initialize function, I’ll extract the search logic to a new function inside the Search class. We can first check if the form exists and return false if it doesn’t. If the form didn’t exist, that would be because you loaded the JavaScript on another page that didn’t have an element with the idea of search-form present.

The new search function will live inside the Search class and handle most of the logic we need.

Inside the function, we first query for the input field where a user will enter their search query.

We’ll check if the field exists with a simple if statement and then process to listen for the forms submit event.

Inside the body of the submit event function, we use the built-in Fetch API to handle AJAX requests to the MealDB API.

What’s Happening Here?

A bunch is going on here, so I’ll try to unpack everything.

We first set up our API URL and assign it to a constant variable called API_URL. Since the MealDB API is free for educational use, an API key of 1 is already within the URL. Using a private API or something more sophisticated may require additional steps to optimize this work.

I added another variable constant for SEARCH_BY_NAME as the API allows you to perform different styles of searches. In this tutorial, we are focused on meal names.

Inside the body of the submit addEventListener function, I return a fetch request to a dynamic URL built with the variables we made at the top of the file. The end of the URL takes in a new instance of the URLSearchParams interface.

This interface will format our query in a way the API will accept automatically, which is a big-time saver. Inside the URLSearchParams instance, we can pass an object that contains a key-value pair. The key (s) is what the MealDB API expects. The value (searchField.value.replace(/\s+/g,)) is the value of the search input the user keys text into.

The replace method you see strips out all white space if the string were to happen to contain any.

The fetch API lets you set what type of HTTP request to perform. We want to “get” data back, so I passed “GET” as the method option.

Promises, Promises

Returning data from a fetch request involves something known as Promises in JavaScript. A Promise is a way to check the status of an HTTP request and perform logic based on that status.

If the Promise has been “fulfilled”, we use a then() method to handle the response and do something with the data. The response that comes back is often JSON data, so we return the response.json() data and perform another then() function where we finally have access to the actual data.

In this example, we return all meals that match the user’s query in the search form. If meals exist, we call a function I created further down the class called this.displaySearchResults(data.meals) and pass in the data for use there.

In this instance, the this keyword refers to the parent Search class.

If there are no results, we can update the div#search-results container with a text string telling the end user what happened.

Finally, if there is an error in the fetch request, we can fall back to the catch() method and display the error in whichever manner we prefer.

Displaying Results

Let’s display some results inside the displaySearchResults function I mentioned before. Inside the Search class, add the following:

If you recall, inside the search() function, we called the displaySearchResults() function and passed in the data from the API request. This data is an Array of meals that might exist in the MealDB API based on the end user’s search query. If data returns, we want to update the search page content with a list of those results.

The displaySearchResults() function first empties the existing HTML content inside the search-results div.

Then we iterate each result using the forEach() method. This method allows you to loop over each result and perform logic.

In our case, I looped through each meal that returns from the API and then assign its content to a custom template. We use JavaScript template literals and string interpolation to map the data in a much easier way than previous versions of JavaScript would allow.

I used a simple console.log statement within the forEach loop to know what was available to use in the template.

Finally, on each iteration of the forEach loop, I used a hand method known as insertAdjacentHTML, which allows you to do just that. HTML can be inserted in various ways, so check out the specification on it.

Because we are building a list, I want to add each new result to the entire list, so the position of beforeend makes the most sense.

Now try searching for a favorite food and see if any meals return in the result lists.

Search results featuring a new recipe resultSearch results featuring a new recipe resultSearch results featuring a new recipe result

With any success, we see some meals!

Closing Thoughts

This tutorial taught you how to combine JavaScript and an API to make a rich, inspirational search tool for some tasty meals. From here, I’d recommend expanding the search criteria to categories and whatever else the MealDB API offers. Happy coding!

More API-Based JavaScript Tutorials

Check out these project-based tutorials to help you learn how APIs work.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.