I am having trouble with making an API call in Next.js that is deleting an item in a database. I am using the "body" field of the fetch to send a string to the API. The fetch call is being made in a Next.JS page and the API endpoint is in the API folder generated by Next.js. When I attempt the console.log the body from the request it is returning an empty object. Below will be the code for the page and then the code for the API endpoint. A screenshot of the console.log from the API endpoint will also be given.
Page
const handleRemoveItem = useCallback(async(event) => {
event.preventDefault()
var itemSKU = event.target.value;
const response = await fetch('/api/SB-RemoveProduct', {
method:'POST',
body: itemSKU
}).then((r) => {
return r
}).catch((err) => {
throw(err)
});
var deleteConfirm = await response.json();
console.log(deleteConfirm);
},[])
API endpoint
export default withSession(async (req, res) => {
var itemSKU = req.body
console.log("You are here 1");
console.log(itemSKU);
switch (req.method) {
case 'POST': {
var productRemoved = await removeProduct(itemSKU, req, res)
return productRemoved;
break
}
case 'GET': {
console.log('try writting a route')
break
}
case 'DELETE': {
console.log('try writting a route')
break
}
case 'UPDATE': {
console.log('try writting a route')
break
}
}
});
export const removeProduct = async (itemSKU, req, res) => {
var params = {
TableName: "products",
Key: itemSKU
}
console.log("You are here 2");
console.log(itemSKU); // this console.log and the one above both return {}
DB.delete(params, function(err, data) {
if (err) {
console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
res.status(200).send(data)
}
});
}
EDIT 1:
After receiving some feedback, I added headers with the 'Content-Type': 'text/plain', 'Accept': 'text/plain' and ended with the same result. I also verified that the variable that I am passing into the body is a string. Below will be page for the code updated.
const handleRemoveItem = useCallback(async(event) => {
event.preventDefault()
var itemSKU = event.target.value;
console.log(typeof(itemSKU));
const response = await fetch('/api/SB-RemoveProduct', {
method:'POST',
body: itemSKU,
mode: "cors",
headers: {
'Accept': 'text/plain',
'Content-Type': 'text/plain'
},
}).then((r) => {
return r
}).catch((err) => {
throw(err)
});
var deleteConfirm = await response.json();
console.log(deleteConfirm);
},[])
EDIT 2:
Following the suggestions from a solution below, I was able to return a different value for itemSKU than what I had before. This time, instead of the item being empty, it returned as undefined. The changes I made are below:
page:
const handleRemoveItem = useCallback(async(event) => {
event.preventDefault()
var itemSKU = event.target.value;
console.log(typeof(itemSKU));
const response = await fetch('/api/SB-RemoveProduct', {
method:'POST',
body: JSON.stringify({itemSKU}),
}).then((r) => {
return r
}).catch((err) => {
throw(err)
});
var deleteConfirm = await response.json();
console.log(deleteConfirm);
},[])
API Endpoint:
export default withSession(async (req, res) => {
var itemSKU = req.body.itemSKU //req.body.itemSKU is returning undefined.
console.log("You are here 1");
console.log(itemSKU);
switch (req.method) {
case 'POST': {
var productRemoved = await removeProduct(itemSKU, req, res)
return productRemoved;
break
}
case 'GET': {
console.log('try writting a route')
break
}
case 'DELETE': {
console.log('try writting a route')
break
}
case 'UPDATE': {
console.log('try writting a route')
break
}
}
});
export const removeProduct = async (itemSKU, req, res) => {
var params = {
TableName: "products",
Key: itemSKU
}
console.log("You are here 2");
console.log(itemSKU);
// DB.delete(params, function(err, data) {
// if (err) {
// console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
// } else {
// console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
// res.status(200).send(data)
// }
// });
}
CodePudding user response:
remove the headers, including Content-type: plain/text
, then...
In your request, change
body: itemSKU,
to
body: JSON.stringify({ itemSKU });
In your API, you can
console.log('req.body.itemSKU', req.body.itemSKU)
Eventually...
//client side
fetch('/api/...', { method: 'POST', body: JSON.stringify({...}))
.then(res => res.json())
.then(data => console.log('data', data));
//prints { value1: 'abc', value2: 'efg'}
Then on API side
export default async(req, res) => {
console.log('req.body.itemSKU', req.body.itemSKU);
res.json({ value1: 'abc', value2: 'efg'})
}