Home » NextJS » How to make Frontend ready for PUT ?

How to make Frontend ready for PUT ?

How to make Frontend ready for PUT

To make your frontend ready for PUT (update) requests, you’ll need to add the ability to:

  1. Select a product for editing.
  2. Pre-fill the form with the product’s existing data.
  3. Send a PUT request to update the product on the backend.
  4. Update the product in the frontend state after a successful update.

Setup the NextJS Application

Install everything

npx create-next-app@latest my-next-app

npm install axios

Create the UI ( Form ) + Axios PUT Query

import { useEffect, useState } from 'react';
import axios from 'axios';

export default function Products() {
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [name, setName] = useState('');
  const [price, setPrice] = useState('');
  const [isEditing, setIsEditing] = useState(false); // Track edit mode
  const [editId, setEditId] = useState(null); // Store ID of the product being edited

  useEffect(() => {
    fetchProducts();
  }, []);

  const fetchProducts = async () => {
    try {
      const response = await axios.get('http://localhost:5000/products');
      setProducts(response.data);
      setLoading(false);
    } catch (error) {
      console.error('Error fetching products:', error);
    }
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      if (isEditing) {
        // Update product with PUT request
        const updatedProduct = { name, price };
        await axios.put(`http://localhost:5000/products/${editId}`, updatedProduct);

        // Update product in the state
        setProducts(
          products.map((product) =>
            product.id === editId ? { ...product, name, price } : product
          )
        );
        setIsEditing(false); // Exit edit mode
        setEditId(null); // Reset editId
      } else {
        // Add new product with POST request
        const newProduct = { name, price };
        const response = await axios.post('http://localhost:5000/products', newProduct);
        setProducts([...products, response.data]); // Add product to state
      }

      // Clear form fields
      setName('');
      setPrice('');
    } catch (error) {
      console.error('Error submitting product:', error);
    }
  };

  const handleEdit = (product) => {
    setIsEditing(true);
    setEditId(product.id); // Set the ID of the product being edited
    setName(product.name); // Pre-fill form with product's name
    setPrice(product.price); // Pre-fill form with product's price
  };

  if (loading) return <p className="text-center">Loading...</p>;

  return (
    <div className="p-6">
      <h1 className="text-2xl font-bold mb-4">
        {isEditing ? 'Edit Product' : 'Add Product'}
      </h1>

      {/* Add / Edit Product Form */}
      <form onSubmit={handleSubmit} className="mb-6">
        <div className="mb-4">
          <label className="block mb-2">Product Name:</label>
          <input
            type="text"
            value={name}
            onChange={(e) => setName(e.target.value)}
            className="border rounded px-4 py-2 w-full"
            required
          />
        </div>
        <div className="mb-4">
          <label className="block mb-2">Price:</label>
          <input
            type="number"
            value={price}
            onChange={(e) => setPrice(e.target.value)}
            className="border rounded px-4 py-2 w-full"
            required
          />
        </div>
        <button
          type="submit"
          className={`${
            isEditing ? 'bg-yellow-500' : 'bg-blue-500'
          } text-white px-4 py-2 rounded hover:opacity-90`}
        >
          {isEditing ? 'Update Product' : 'Add Product'}
        </button>
      </form>

      {/* Product Table */}
      <table className="table-auto w-full border-collapse border border-gray-300">
        <thead>
          <tr>
            <th className="border px-4 py-2">ID</th>
            <th className="border px-4 py-2">Name</th>
            <th className="border px-4 py-2">Price</th>
            <th className="border px-4 py-2">Actions</th>
          </tr>
        </thead>
        <tbody>
          {products.map((product) => (
            <tr key={product.id}>
              <td className="border px-4 py-2">{product.id}</td>
              <td className="border px-4 py-2">{product.name}</td>
              <td className="border px-4 py-2">${product.price}</td>
              <td className="border px-4 py-2">
                <button
                  onClick={() => handleEdit(product)}
                  className="bg-yellow-500 text-white px-2 py-1 rounded hover:bg-yellow-600"
                >
                  Edit
                </button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}