To make your frontend ready for PUT
(update) requests, you’ll need to add the ability to:
- Select a product for editing.
- Pre-fill the form with the product’s existing data.
- Send a
PUT
request to update the product on the backend. - 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>
);
}