DEV Community

Bobby Hall Jr
Bobby Hall Jr

Posted on

The Power of Promises with Next.js: Building a Pizza Delivery App 🍕

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);
  });
};
Enter fullscreen mode Exit fullscreen mode

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);
};
Enter fullscreen mode Exit fullscreen mode

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);
  });
};
Enter fullscreen mode Exit fullscreen mode

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.');
  }
};
Enter fullscreen mode Exit fullscreen mode

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);
};
Enter fullscreen mode Exit fullscreen mode

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);
};
Enter fullscreen mode Exit fullscreen mode

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.');
  }
};
Enter fullscreen mode Exit fullscreen mode

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.');
  }
};
Enter fullscreen mode Exit fullscreen mode

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


Subscribe to my newsletter where you will get tips, tricks and challenges to keep your skills sharp. Subscribe to newsletter

Top comments (0)