Ricky GoacherRicky Goacher

FoodFinder NextJs App

Cover Image
Ricky GoacherRicky Goacher
Published Date: 09/07/20244 Minutes

Introduction

I began this project to improve my knowledge of React and NextJs. The challenge here was to gain a better understanding of client and server side components, working with APIs and building requests based on potentially complex user input.

Project details

This project was built using the Edamam API, more information can be found here https://www.edamam.com/.

The application was built using NextJs, modular CSS and fetch to communicate with the Edamam API.

Key features of the application

The FoodFinder application allows users to configure filters to find interesting recipes based on their selections, when applying the filters the recipe listing page loads a random set of recipes for the user to select.

FoodFinder

When selecting a recipe, the user is taken to a page which displays detailed information about each recipe. The includes information like ingredients, nutrition and a link to the step by step instructions.

Recipe display page

Recipe details - information

Users are also able to search to locate recipes using keywords. For example, users are able to search for the keyword "chicken" to receive a list of recipes which contain chicken.

Recipe search functionality

How the application was built

Reading through the documentation and testing out to functionality available I began to plan out what I wanted to achieve with my application. Using the information provided I was able to identify what requests were available to me and how to structure my requests.

Edamam

Expanding the Recipe search section I was able to identify what parameters are available to me.

Recipe Search

Recipe listing page

After generating the Next application I used the information in the documentation to begin describing the information returned from the requests using Typescript. This is done to make the data easier to work with later when utilising the information.

typescript

I then began building out the information required for the filters to function. I did this by creating and object of arrays with the various filter types and options.

Filter object

I then created a new component to handle the filter functionality, within this component I imported the filter object and used the data to generate a set of checkboxes and labels.

Filter Generation

This maps over the filters to create each set of filters, then maps over the set of filters to build out each set of labels and checkboxes.

A sidebar structure was then created along with styles and dummy functions required later.

Filter render sidebar

I then setup the various states required for handling the default states of the checkboxes and managing the current state. These use the filter object the generate an empty object using the same structure which can be manipulated at a later time.

filter states

Next I began to build out the checkbox onChange function, this function takes in the position and type to update the corresponding entry in the checked filters state, it also matches the checked filters state with the selected filters, this is done to build an object which contains the parameter to use in the fetch request.

onchange filter

An API directory and file was then created to handle requesting data.

fetch api

This function receives the parameters from the selected filters state, prepares it and passes the information into the URL. This returns recipes based on parameters passed into it.

This function is then imported into the filter module to be updated with the state of the filters on submit, an initial filter selection is also passed to fetch data on page load.

Initial recipes

This function is called on first page load using useEffect().

The final step for the functionality on this page was to display the details of the recipes returned and create links to be used to take the user to the recipe display page. To handle this I created a new component and passed in the recipe data as props for the component.

recipe card

card component

Alongside various bits on minor functionality and component styling, the end result was this

Lisitng page filters

Recipe search

Using the API documentation, I began to setup a recipe search input to be part of the header. To do this I created an additional function which takes in a query as a parameter.

search func

I then created a component that displays the search box, listens for the users input and utilised a debounce function to wait for the user to finish typing before sending the request.

debounce

When the data is returned, the results are looped over and displayed in a popup below the search.

generate search results

search results

Recipe display page

The final step for the application was to created the display page for the recipe and display all the details for recipe. To do this I needed to use NextJs routing using the [slug] directory to handle the random page generation based on URL.

For the display page I created a new function for fetching recipe specific data, this used the [slug] information as a parameter for fetching the data.

recipe fetch

recipe fetch async

Once this data was made available in the page I built out several components and the layout and styling for the page. This was the end result.

Recipe display page

Recipe details - information