I make a crud with products
I send an http request to the /api/deleteProduct route with the product id to retrieve it on the server side and delete the product by its id
To create a product it works only the delete does not work
pages/newProduct.js :
useEffect(() => {
async function fetchData() {
const res = await axios.get('/api/products');
setProducts(res.data);
}
fetchData();
}, []);
const handleSubmit = async (event) => {
event.preventDefault();
const formData = new FormData();
formData.append('picture', picture);
formData.append('name', name);
formData.append('price', price);
formData.append('category', category);
formData.append('description', description);
try {
const res = await axios.post('/api/createProduct', formData);
console.log(res.data);
} catch (error) {
console.log(error);
}
};
const handleDelete = async (id) => {
try {
await axios.delete(`/api/deleteProduct?id=${id}`);
setProducts(products.filter(product => product._id !== id));
} catch (error) {
console.log(error);
}
};
api/deleteProduct.js :
import Product from '../../models/Products';
import { initMongoose } from '../../lib/mongoose';
initMongoose();
export const handleDelete = async (req, res) => {
if (req.method === 'DELETE'){
try {
const { id } = req.params
const product = await Product.findByIdAndRemove(id);
if (!product) {
return res.status(404).json({ message: 'Product not found' });
}
return res.status(200).json({ message: 'Product deleted successfully' });
} catch (error) {
console.log(error);
return res.status(500).json({ message: 'Database error' });
}
}};
I have a 500 error but no error in the server side console and the console.log is not showing like the file was not read
Based on the code you've shared, it seems that the problem may be with the way that the delete request is being handled on the frontend. Specifically, in this line:
await axios.delete("/api/deleteProduct", { params: { id } });
The delete request is supposed to receive the id of the product that should be deleted as a query parameter, but it is being passed as a request body.
Instead of passing it as a parameter, you should pass it as a query parameter by changing it to
await axios.delete(`/api/deleteProduct?id=${id}`);
Also, in your api/deleteProduct.js, you should change the following line:
const { id } = req.query;
to
const { id } = req.params;
Also, you should make sure that the server is running and that the api endpoint '/api/deleteProduct' is accessible and handling the request correctly.
For the last, make sure that the product model is imported and initialized correctly and the database connection is established.
Hope that it solves your problem or, at least, helps :))
I succeeded, I put this (server side):
const { id } = req. query;
and (client side):
await axios.delete(/api/deleteProduct?id=${id});
and I exported my function like this:
export default async function handleDelete(req, res) {
Related
I want to search for my product to display on my browser by clicking the search button.
I can search products by Postman API nicely. But, I have no idea to display data by clicking the search button.
product.js
router.get("/find/:id", async (req, res) => {
try {
const product = await Product.findById(req.params.id);
res.status(200).json(product);
} catch (err) {
res.status(500).json(err);
}
});
//GET ALL PRODUCTS
router.get("/", async (req, res) => {
const qNew = req.query.new;
const qCategory = req.query.category;
try {
let products;
if (qNew) {
products = await Product.find().sort({ createdAt: -1 }).limit(1);
} else if (qCategory) {
products = await Product.find({
categories: {
$in: [qCategory],
},
});
} else {
products = await Product.find();
}
res.status(200).json(products);
} catch (err) {
res.status(500).json(err);
}
});
Navbar.js
const Navbar = () => {
return (
<Button>Search</Button>
);
};
export default Navbar;
You're going to want to use Axios to make a request from your react application.
To do this you need to install and require Axios into your react application.
This code will allow you to make a request to your express application:
async function getProduct(productID) {
try {
const response = await axios.get(`/find/${productID}`);
console.log(response);
} catch (error) {
console.error(error);
}
}
This is going to only work when you know what the ID of the product you're searching is. If you have another endpoint on your server to search for a product via name you can change the endpoint accordingly. Here are the Axios docs.
Hope this helps. Thanks!
I'm trying to query from a table where the teacherId is equal to the teacherId of the person that logs in but I can't pass that teacherId from the front-end to the back-end.
This is the back end
app.get("/api/get", async(req,res) => {
const teacherId = req.body.teacherId
connection.query(
"SELECT class FROM homework WHERE teacherID = ?",
[teacherId],
(err, result) => {
if (result){
res.send({ message: result })
} else{
console.log(err)
}
}
)
})
This is the front end
useEffect(() => {
Axios.get("http://localhost:1337/api/get", {
teacherId: teacherId
}).then((response) => {
if(response){
setDisplayHomework(response.data.message)
} else{
console.log("error")
}
})
})
const teacherId = localStorage.getItem("teacherId")
I think the problem lies where it says teacherId: teacherId but I don't know why.
You need to use
Axios.get("http://localhost:1337/api/get", {
params: { teacherId }
});
and use req.query.teacherId to read it
If you see the Axios.get signature it is
axios.get(url[, config])
in contrast to
axios.post(url[, data[, config]])
which passes the data as the second argument.
That is because the body in GET requests is not used by the servers. Read HTTP GET with request body for more on this.
Usually you do not send a body with a get request. Put the teacher id into the url. Then this is called path variable.
app.use('/teacher/:teacherId', function(req, res, next) {
console.log(req.params.teacherId);
next();
})
Get requests don't have request bodies unlike post requests, as such the Axios.get function shouldn't have a second parameter for the body. Instead pass your parameters as a url, like this:
useEffect(() => {
Axios.get("http://localhost:1337/api/get?teacherId="+teacherId).then((response) => {
if(response){
setDisplayHomework(response.data.message)
} else{
console.log("error")
}
})
})
Then in your backend code use req.params to access the get request url parameters:
app.get("/api/get", async(req,res) => {
const teacherId = req.params.teacherId
connection.query(
"SELECT class FROM homework WHERE teacherID = ?",
[teacherId],
(err, result) => {
if (result){
res.send({ message: result })
} else{
console.log(err)
}
}
)
})
I'm new to Next Js and functional comoponents. I'm trying to retrieve data from /api/retrieve2
//this is retrieve page
export default function Retrieve() {
const onSubmit = async data => {
const { user } = await axios.post("/api/retrieve2", data);
console.log(user) // user here is undefined
};
return (...);
}
//this is retrieve2, inside the API folder
export default async (req, res) => {
try {
const { data } = await axios.post(myBackendUrl, req.body);
console.log(data) //this is printing the right data - { email: 'casas#gmail.com', code: '123123' }
res.json(data);
} catch (e) {
res.json({ err: e.message || e });
}
};
What am I missing, is this something about Next? About functional components?
You should read about ES6 destructuring
You try to destructure user but the axios respons witch is a object doesnt contain the key user
For data it works because there is a data property in the response
Here are all properties that you can destructure:
{ data, status, statusText, headers, config, request }
You need to get the full URL to make http request to using getInitialProps, here Home is the name of your component
const Home = ({ENDPOINT}) => {
const onSubmit = async data => {
const { data } = await axios.post(`${ENDPOINT}/api/retrieve2`, data);
// consider changing `user` here to `data` since Axios stores response in data object
console.log(data) // should be defined
};
return (...);
}
Home.getInitialProps = ctx => {
const ENDPOINT = getEndpoint(ctx.req);
return { ENDPOINT };
};
// You should store this somewhere you can reuse it
export function getEndpoint(req) {
return !!req
? `${req.headers['x-forwarded-proto']}://${req.headers['x-forwarded-host']}`
: window.location.origin;
}
I'm building a Node.js PostgresSQL Server from which I get my Data and then I want to show them in my Vue Client. Now I'm stuck at adding new columns from my client. When I try to add new data i get this error: (cannot read isbn of undefined) https://imgur.com/bPBXQvi
I already checked the order of the parameters that are send and they are in the correct order.
My Axios Call:
async addBuch(isbn,erschdat,titel,preis,verlagname,authorname){
await axios.post('http://localhost:3000/buch/add', {isbn, erschdat,titel,preis,verlagname,authorname})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error)
});
}
My Route(the first one is for deleting a column which is working):
app.get('/buch/del/:isbn', async (req, res) => {
res.send(await delBuch(req.params.isbn));
});
app.post('/buch/add', async (req, res) => {
res.send(await addBuch(req.body.isbn,req.body.erschdat,req.body.titel,req.body.preis,req.body.verlagname,req.body.authorname));
});`
the "addBuch" method:
async function addBuch(isbn, erschdat, titel, preis, verlagname, authorname) {
const client = await pool.connect();
try {
var data;
var res = await client.query(`INSERT INTO buch ("isbn", "erscheinungsdatum", "titel", "preis", "verlagname", "authorname") VALUES($1,$2,$3,$4,$5,$6)`, [isbn, erschdat, titel, preis, verlagname, authorname]);
return data = {
'isbn': isbn,
'erscheinungsdatum': erschdat,
'titel': titel,
'preis': preis,
'verlagname': verlagname,
'authorname': authorname
};
}
catch (error) {
console.log(error);
}
}
I have a route in my app that calls the mongoose method findByIdAndRemove. When I test this route in postman, I can successfully delete documents in my database, but when I call this method from my javascript file in the client, I get an error.
I getting a 404 (the response status I dictated if no document can be found). I also get an error in the terminal saying "can't set headers after they are sent." I'm not sure why I'm getting this error. Why is my route working in postman, but not when I call it from the client-side?
How should I get this working?
Here is my route on the server-side:
exports.deleteEmployee = function (req, res, next) {
const id = mongoose.Types.ObjectId(req.body.id);
Employee.findByIdAndRemove(id, (err, employee) => {
if (err) { return next(err); }
// if no employee with the given ID is found throw 400
if (!employee) { res.status(404).json('No employee with that ID'); }
res.status(200).json(employee);
});
};
Here is where I call this route from the client-side:
export const employeeDelete = ({ id }) => {
const props = { id };
return () => {
axios.delete(`${api.API_ROUTE}/employee/delete`, props)
.then(() => {
// push user back to EmployeeList and reset view stack
Actions.employeeList({ type: 'reset' });
})
.catch(err => {
console.log(err);
});
};
};
You're getting "can't set headers after they are sent." error because you're trying to respond with 200 code after having responded with 400 code.
You should surround the response statements with a if/else statement:
if (!employee) { res.status(404).json('No employee with that ID'); }
else{res.status(200).json(employee);}
It turns out the axios delete method does not take a data object, so when I passed the object called props, it never reached the server. I instead passed id as a url parameter like this:
export const employeeDelete = ({ id }) => {
return () => {
axios.delete(`${api.API_ROUTE}/employee/delete/${id}`)
.then(() => {
// push user back to EmployeeList and reset view stack
Actions.employeeList({ type: 'reset' });
})
.catch(err => {
console.log(err);
});
};
};