I've been following a tutorial on Next.js which works with MongoDB. All my requests work fine when sent through Postman, indicating that my API is working as expected. I can send POST, GET and DELETE requests from Postman without any issues.
However, when I send a DELETE request through a function invoked by a button, I get an ERR_CONNECTION_REFUSED error with no other information whatsoever. Can someone point out what I'm doing wrong here?
Here's the code
As you can see I have an update and a delete button making a console log and calling a function respectively. However, the onClick
for the update button isn't firing, and the onClick
for the delete button gives the connection refused error when clicked.
import axios from "axios"
import { useState } from "react"
export default function Index({ products }) {
const [productList, setProductList] = useState(products)
const handleDelete = async (id) => {
try {
const res = await axios.delete("http://localhost:3000/api/products/" id)
setProductList(productList.filter((product) => product._id !== id))
} catch (error) {
console.log(error)
}
}
return (
<div className="container">
<h1 className="display-3 text-center my-5">Admin Dash</h1>
<div className="d-flex justify-content-center">
<div className="col-md-4">
<form action="">
<div className="my-3">
<label htmlFor="productName" className="form-label">Enter Product Name</label>
<input type="text" name="productName" className="form-control" id="productName" />
</div>
<div className="my-3">
<label htmlFor="productDesc" className="form-label">Enter Product Description</label>
<input type="text" name="productDesc" className="form-control" id="productDesc" />
</div>
<div className="my-3">
<label htmlFor="productPrice" className="form-label">Enter Product Price</label>
<input type="number" name="productPrice" className="form-control" id="productPrice" />
</div>
<div className="my-3 d-flex justify-content-center">
<button className="btn btn-primary btn-lg me-3">Upload Image</button>
<button className="btn btn-success btn-lg">Add Product</button>
</div>
</form>
</div>
</div>
<hr />
<div className="d-flex flex-column align-items-center">
<h1 className="display-3 my-3">Listed Products</h1>
<table className="table table-striped mb-5">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Product Name</th>
<th scope="col">Product Description</th>
<th scope="col">Product Price</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
{productList.map(product => (
<tr key={product._id}>
<th scope="row">{product._id}</th>
<td>{product.title}</td>
<td>{product.desc}</td>
<td>{product.prices[0]}</td>
<td>
<button className="btn btn-warning me-3" onClick={() => console.log("Test")}>Update</button>
<button className="btn btn-danger" onClick={() => handleDelete(product._id)}>Delete</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
)
}
export const getServerSideProps = async () => {
const productsList = await axios.get("http://localhost:3000/api/products")
return {
props: {
products: productsList.data
}
}
}
For good measure, here's the API endpoint code as well.
import dbConnect from "../../../lib/dbConnect"
import Product from "../../../models/Product"
export default async function handler(req, res) {
const { method, query:{ id} } = req
dbConnect()
if (method === "GET"){
try {
const product = await Product.findById(id)
res.status(200).json(product)
} catch (error) {
res.status(500).json(error)
}
}
if (method === "POST"){
try {
const product = await Product.create(req.body)
res.status(200).json(product)
} catch (error) {
res.status(500).json(error)
}
}
if (method === "DELETE"){
try {
await Product.findByIdAndDelete(id)
res.status(200).json("Product Deleted!")
} catch (error) {
res.status(500).json("Problem here")
}
}
}
CodePudding user response:
So after an entire night of bashing my head, I figured out what the problem was. In my handleDelete
function, the following line
const res = await axios.delete("http://localhost:3000/api/products/" id)
Will change to:
const res = await axios.delete("http://internalIPhere:3000/api/products/" id)
My guess is that the issue stemmed from the fact that I was running my dev server on a virtual machine and accessing it from the host OS. Since localhost
addresses aren't resolved in my browser hence it wasn't able to reach the API endpoint. As soon as I replaced localhost
with the virtual machine's IP, everything worked fine.