The Power of Promises with Next.js: Building a Pizza Delivery App
In this blog post, we'll explore the power of promises in Next.js by building a Pizza Delivery App. Promises allow us to handle asynchronous operations in a more elegant and structured way, making our code more readable and maintainable. We'll dive into each function of the code and understand how promises are utilized to simulate API calls for adding, editing, and deleting orders.
The full code for our Pizza Delivery App component can be found on GitHub.
Live Demo:
Check it for yourself here: Pizza Ordering App Demo
The PizzaOrder Component
The core of our Pizza Delivery App is the PizzaOrder
component. This component handles the pizza order functionality, including selecting pizzas, placing orders, displaying order status, and managing the order history. Let's break down each function and understand how promises are used.
takeOrder Function
The takeOrder
function is responsible for adding a pizza to the cart. Here's the code:
const takeOrder = (pizza) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const isAvailable = checkAvailability(pizza);
if (isAvailable) {
const updatedCart = [...cart, pizza];
setCart(updatedCart);
resolve(pizza);
} else {
reject(new Error('Sorry, the pizza is not available.'));
}
}, 2000);
});
};
Here, we create a new promise that wraps the asynchronous operation of adding a pizza to the cart. We simulate this operation using setTimeout()
for a delay of 2000 milliseconds (2 seconds). Inside the timeout function, we check the availability of the pizza using the checkAvailability
function. If the pizza is available, we update the cart and resolve the promise with the added pizza. Otherwise, we reject the promise with an error message.
checkAvailability Function
The checkAvailability
function simply checks if the selected pizza is available. Here's the code:
const checkAvailability = (pizza) => {
const availablePizzas = ['Margherita', 'Pepperoni', 'Vegetarian'];
return availablePizzas.includes(pizza);
};
In this function, we define an array of available pizzas and check if the selected pizza exists in the array using the includes
method. The function returns a boolean value indicating the availability of the pizza.
processOrder Function
The processOrder
function handles the processing of the order. It checks if the cart is empty and resolves the promise with the cart items if it's not empty. Here's the code:
const processOrder = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (cart.length >= 0) {
resolve(cart);
} else {
reject(new Error('Cart is empty. Please add pizzas to your order.'));
}
}, 1500);
});
};
Similar to the takeOrder
function, we create a promise and simulate an API call using setTimeout()
. Inside the timeout function, we check if the cart has any items. If it does, we resolve the promise with the cart items. Otherwise, we reject the promise with an error message.
handleOrder Function
The handleOrder
function is the event handler for placing an order. It utilizes the takeOrder
and processOrder
functions to add the selected pizza to the cart and process the order. Here's the code:
const handleOrder = async () => {
try {
setOrderStatus('Placing order...');
const order = await takeOrder(selectedPizza);
console.log(`Successfully added ${order} to the cart.`);
const processedOrder = await processOrder();
console.log('Your order is ready!');
console.log('Ordered Pizzas:', processedOrder);
setOrderStatus('Order placed successfully!');
} catch (error) {
console.error(error.message);
setOrderStatus('Failed to place order.');
}
};
In this function, we set the order status to "Placing order..." to indicate the ongoing process. We then use await
to call the takeOrder
function and add the selected pizza to the cart. Once the pizza is added, we log a success message and call the processOrder
function to process the order. Finally, we update the order status based on the outcome of the order placement.
handleEditOrder Function
The handleEditOrder
function is triggered when the user clicks the "Edit" button for a specific order. It opens a modal to edit the pizza name. Here's the code:
const handleEditOrder = (index) => {
setEditIndex(index);
setNewPizzaName(cart[index]);
setEditModalOpen(true);
};
In this function, we set the editIndex
state to the index of the order being edited. We also set the newPizzaName
state to the current pizza name, and open the edit modal by setting the editModalOpen
state to true
.
handleDeleteOrder Function
The handleDeleteOrder
function is triggered when the user clicks the "Delete" button for a specific order. It opens a confirmation modal before deleting the order. Here's the code:
const handleDeleteOrder = (index) => {
setEditIndex(index);
setDeleteModalOpen(true);
};
Similar to the handleEditOrder
function, we set the editIndex
state to the index of the order being deleted and open the delete modal by setting the deleteModalOpen
state to true
.
handleConfirmEdit Function
The handleConfirmEdit
function is called when the user confirms the edit in the edit modal. It updates the cart with the new pizza name. Here's the code:
const handleConfirmEdit = () => {
try {
const updatedCart = [...cart];
updatedCart[editIndex] = newPizzaName;
setCart(updatedCart);
setEditModalOpen(false);
setOrderStatus('Order edited successfully!');
} catch (error) {
console.error(error.message);
setOrderStatus('Failed to edit order.');
}
};
In this function, we create a new array updatedCart
using the spread operator to copy the existing cart. We update the pizza name at the specified index with the newPizzaName
state. Finally, we update the cart, close the edit modal, and set the order status accordingly.
handleConfirmDelete Function
The handleConfirmDelete
function is called when the user confirms the deletion in the delete modal. It removes the order from the cart. Here's the code:
const handleConfirmDelete = () => {
try {
const updatedCart = [...cart];
updatedCart.splice(editIndex, 1);
setCart(updatedCart);
setDeleteModalOpen(false);
setOrderStatus('Order deleted successfully!');
} catch (error) {
console.error(error.message);
setOrderStatus('Failed to delete order.');
}
};
In this function, we create a new array updatedCart
using the spread operator to copy the existing cart. We use the splice
method to remove the order at the specified index. Finally, we update the cart, close the delete modal, and set the order status accordingly.
Conclusion
In this blog post, we explored the power of promises in Next.js by building a Pizza Delivery App. We learned how promises can be used to handle asynchronous operations in a structured and readable manner. By using promises and simulating API calls with setTimeout()
, we were able to add, edit, and delete orders seamlessly. Leveraging promises helps improve code organization, maintainability, and overall developer experience.
The full code for our Pizza Delivery App component can be found on GitHub.
Live Demo:
Check it for yourself here: Pizza Ordering App Demo
Top comments (0)