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.
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.
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.
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.
Expanding the Recipe search section I was able to identify what parameters are available to me.
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.
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.
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.
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.
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.
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.
An API directory and file was then created to handle requesting data.
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.
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.
Alongside various bits on minor functionality and component styling, the end result was this
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.
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.
When the data is returned, the results are looped over and displayed in a popup below the search.
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.
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.