All network requests to TheMealDB are centralized in a single file:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Miguelcds/Recipe-Hub/llms.txt
Use this file to discover all available pages before exploring further.
src/services/api.js. No component or hook fetches data directly — they all call one of the exported functions from this module.
This keeps network logic out of the UI layer and makes it straightforward to test, mock, or swap the data source later.
Full source
src/services/api.js
Private helpers
Two private functions validate every response before any data is processed. They are not exported and cannot be called outside this module.apiOk(res)
apiOk(res)
Checks the HTTP response status. Called immediately after every Throws:
fetch call.Error with message "The Meal Error: {status}" when res.ok is false (i.e., any non-2xx HTTP status code).apiMealOk(data)
apiMealOk(data)
Checks the parsed JSON payload. Called after Throws:
res.json() to confirm that the API returned at least one meal.Error with message "No se ha localizado ninguna receta con los datos introducidos" when data.meals is null, undefined, or an empty array. TheMealDB returns { "meals": null } for queries that match nothing.Exported functions
getRecipeByName(search)
Searches TheMealDB by meal name and returns a list of matching meals.
Parameters
The meal name to search for. Passed directly to the
s query parameter of the TheMealDB search endpoint.Promise<Array<{id: string, name: string, picture: string, category: string}>>
TheMealDB meal ID (
idMeal).Meal name (
strMeal).URL to the meal thumbnail (
strMealThumb).Meal category (
strCategory).apiOkthrows if the HTTP request fails (non-2xx status).apiMealOkthrows if no meals match the search query.
getRecipeById(id)
Fetches the full detail record for a single meal by its TheMealDB ID.
Parameters
The TheMealDB meal ID. Typically obtained from a
getRecipeByName or getRandomRecipes result.Promise<{id, name, picture, category, instructions, video, ingredients}>
TheMealDB meal ID.
Meal name.
Thumbnail URL.
Meal category.
Full cooking instructions (
strInstructions).YouTube URL for the recipe (
strYoutube). May be an empty string.Parsed list of ingredients. See below for the item shape.
strIngredient1–strIngredient20) rather than an array. getRecipeById normalizes this into a clean array:
Filter empty slots
If the ingredient string is falsy or whitespace-only (
ingredient.trim() === ""), the slot is skipped. TheMealDB fills unused slots with "" or null.apiOkthrows if the HTTP request fails.apiMealOkthrows if the ID does not exist in TheMealDB.
getRandomRecipes()
Fetches 9 random meals in parallel and returns them as an array.
This function takes no parameters.
Returns
Promise<Array<{id: string, name: string, picture: string, category: string}>> — always resolves to exactly 9 items when successful.
Parallel fetch strategy
The function uses Array.from with a mapping function to create 9 fetch Promise objects simultaneously, then settles them all with Promise.all:
parallel fetch
apiOkthrows if any of the 9 HTTP responses is not OK. BecauseforEach(apiOk)runs synchronously afterPromise.all, the first failing response causes an immediate throw.apiMealOkthrows if any response body contains no meals.
Error handling
Errors propagate through a consistent chain from the service layer to the UI:- Service throws
- Hook catches
- Page renders
src/services/api.js
Error objects with descriptive messages, the hook does not need to distinguish between error types — it always sets apiError to error.message and the page renders it directly.
Extending the service layer
adding a new endpoint