https://github.com/deepak9011/recipe-newer
Recipe Newer is a React-based web app for discovering and exploring global recipes, featuring search, category and area filters, and a custom domain on Azure. Integrating TheMealDB API, it provides a seamless culinary experience with efficient data fetching for detailed recipe views.
https://github.com/deepak9011/recipe-newer
azure-app-service css3 git html5 integration javascript reactjs restful-api vite
Last synced: 3 months ago
JSON representation
Recipe Newer is a React-based web app for discovering and exploring global recipes, featuring search, category and area filters, and a custom domain on Azure. Integrating TheMealDB API, it provides a seamless culinary experience with efficient data fetching for detailed recipe views.
- Host: GitHub
- URL: https://github.com/deepak9011/recipe-newer
- Owner: Deepak9011
- Created: 2024-08-13T13:29:41.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2025-03-05T14:05:26.000Z (over 1 year ago)
- Last Synced: 2025-03-05T15:22:50.575Z (over 1 year ago)
- Topics: azure-app-service, css3, git, html5, integration, javascript, reactjs, restful-api, vite
- Language: JavaScript
- Homepage: https://recipenewer.deepakagrawal.xyz/
- Size: 10.4 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Recipe Newer

Embark on a culinary journey with Recipe Newer, your ultimate companion for exploring a world of flavors. Discover delightful dishes from around the globe with just a search. From savory classics to sweet sensations, Recipe Newer guides you through a treasure trove of recipes, helping you create masterpieces in your kitchen.
[Click here to visit the website!](https://recipenewer.deepakagrawal.xyz/))
## Technologies
Recipe Newer is crafted using modern web technologies to ensure a smooth, engaging, and efficient single-page user experience. Here's a glimpse into the technologies that power the app:
### React
The frontend of Recipe Newer is built with React, a powerful JavaScript library for building user interfaces. React's component-based architecture enhances code reusability and helps manage the app's complex UI components.
### Vite
Vite is the build tool of choice for Recipe Newer. Its rapid build speed and modern development server create a lightning-fast development environment, contributing to a more efficient development process.
### TheMealDB API
Recipe Newer integrates seamlessly with TheMealDB API to fetch an extensive variety of recipes. As a publicly accessible API, it provides a wealth of culinary information, allowing users to discover and explore diverse dishes effortlessly.
### HTML5 & CSS3
The app's structure and styling are built using HTML5 for content and CSS3 for styling. This combination creates visually appealing recipe cards, search interfaces, and a cohesive user interface.
### JavaScript ES6+
Modern JavaScript features and syntax, such as ES6+, are utilized to write clean, concise, and maintainable code. These features enhance the app's interactivity and functionality.
### Git & GitHub
Version control is managed using Git, allowing for efficient code management. GitHub provides a platform for hosting and sharing the app's source code.
### Deployment on Netlify
Recipe Newer is optimized for deployment on Netlify, a powerful platform for hosting static websites and web applications. Netlify's seamless integration with GitHub streamlines the deployment process, ensuring that the app is easily accessible to users online.
## Features
Recipe Newer is a web application designed to make your culinary journey enjoyable and effortless. With a focus on simplicity and discovery, Recipe Newer empowers users to explore a diverse range of recipes and unleash their inner chef. Here are some of the key features:
### Search recipes by name
* Users are able to type into a search bar to search for recipes by name
### Filter recipes by category
* Users are able to filter recipes by category
### Filter recipes by area
* Users are able to filter recipes by areas of the world (countries)
### Lookup a random recipe
* Users are able to cycle through random recipes on click
### List all recipes by the first letter
* Users are able to list all recipes whose name begins with the clicked letter
### View recipe details
* Users are able to click on any recipe card to view the details of the clicked recipe (name, ingredients, etc.)
### Save recipes
* Users are able to save recipes which can be viewed later in the favorites page
## Frontend Routing
* `Route`
* `Component`
* Description
***
* `/`
* `Home`
* The default homepage containing the 'search' feature of the application
* `/:id`
* `RecipeDetailView`
* Displays the detailed view of a recipe which contains all of the recipe information (such as name, ingredients, etc.)
* `/favorites`
* `Favorites`
* Displays all of the users favorited recipes, if any
* `/category`
* `Categories`
* Displays all of the available recipe categories
* `/category/:category`
* `CategoryView`
* Displays all of the recipes that fall under a category
* `/area`
* `Areas`
* Displays different country flags so users can filter recipes by areas of the world
* `/area/:area`
* `AreaView`
* Displays all of the recipes that fall under an area (country)
* `/random`
* `RecipeDetailView`
* Displays the recipe detail view of a random meal every time the user clicks
* `/alphabet/:letter`
* `Alphabet`
* Displays all of the recipes whose name begins with the letter the user clicked
## Challenge
During the development of Recipe Newer, one notable challenge I encountered revolved around making an API call for each element in an array. This challenge emerged when I wanted users to be directed to the Recipe Detail View by clicking on a Recipe Card component whose data was being displayed by JSON that was fetched from a Filter by Category API request. The problem was that the data returned by the endpoint I was using didn't display all of the recipe information, only the ID and a few other pieces of data. In order to pass down the relevant information to the Recipe Detail View component, I had to iterate over each element of the fetched JSON data and initiate a second API call for each element that would allow me to look up all of the recipe information for each ID.
To overcome this challenge, I had to utilize the `Promise.all()` method from the Promise object, which I had never used before. This method proved to be a powerful solution for handling multiple asynchronous operations simultaneously. By wrapping each API call inside a Promise and then using `Promise.all()`, I was able to execute all the API calls concurrently and efficiently collect the required data.
```javascript
export async function getMealsByCategory(setState, category) {
try {
const url = `https://www.themealdb.com/api/json/v1/1/filter.php?c=${category}`
const resp = await fetch(url);
const data = await resp.json();
const newDataArray = await Promise.all(
data.meals.map(async (meal) => {
const resp = await fetch(`https://www.themealdb.com/api/json/v1/1/lookup.php?i=${meal.idMeal}`);
const data = await resp.json();
return await data.meals[0];
})
)
setState(newDataArray)
} catch(err) {
console.error(err)
}
}
```
This function was able to return data that originally looked like this:
```json
[
{
"strMeal": "Baked salmon with fennel & tomatoes",
"strMealThumb": "https://www.themealdb.com/images/media/meals/1548772327.jpg",
"idMeal": "52959"
},
{
"strMeal": "Cajun spiced fish tacos",
"strMealThumb": "https://www.themealdb.com/images/media/meals/uvuyxu1503067369.jpg",
"idMeal": "52819"
},
{
"strMeal": "Escovitch Fish",
"strMealThumb": "https://www.themealdb.com/images/media/meals/1520084413.jpg",
"idMeal": "52944"
},
...
]
```
And in the end, looked like this:
```json
[
{
"idMeal": "52959",
"strMeal": "Baked salmon with fennel & tomatoes",
"strCategory": "Seafood",
"strArea": "British",
...
},
{
"idMeal": "52944",
"strMeal": "Escovitch Fish",
"strCategory": "Seafood",
"strArea": "Jamaican",
...
},
...
]
```
This challenge not only expanded my knowledge of asynchronous operations but also introduced me to a valuable tool in JavaScript's Promise API. I was able to apply this solution to several other API function calls as well, further solidifying my understanding. However, given that this is the function where I first encountered the problem and found the solution, I wanted to go ahead and highlight this one specifically.
## Resources
* [Carousel Component](https://mdbootstrap.com/docs/react/components/carousel/)
* [Images for Carousel Component](https://unsplash.com/)
* [SVG Icons](https://www.svgrepo.com/)
* [SVG Page Dividers](https://omatsuri.app/)
* [Font Awesome Icons](https://fontawesome.com/)
* [Custom Fonts](https://fonts.google.com/)
* [CSS Loader](https://loading.io/css/)
* [Pass Props Through React Router's Link Component](https://ui.dev/react-router-pass-props-to-link)
* [Scroll To Top on Page Transition](https://stackoverflow.com/questions/36904185/react-router-scroll-to-top-on-every-transition)
* [Make API Calls For Each Element In An Array](https://stackoverflow.com/questions/66505445/how-to-make-api-calls-for-each-element-in-array)