3

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)
        }
    });
    
}

enter image description here

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)
    //     }
    // });
    
}

8
  • 1
    You're sending a text/plain request body. Is that what you're wanting to send? Is the API configured to handle such a request content-type? Commented Feb 15, 2022 at 4:47
  • So normally I would use JSON.stringify() when passing information to the request body, but doing so returns the exact same result. Commented Feb 15, 2022 at 5:17
  • You would also need to set the appropriate content-type header Commented Feb 15, 2022 at 5:19
  • Sorry, I am still a pretty novice dev, do you mind explaining the content-type header and what I would need to change it to? Commented Feb 15, 2022 at 5:57
  • See this answer Commented Feb 15, 2022 at 6:00

2 Answers 2

4

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'})
}
Sign up to request clarification or add additional context in comments.

12 Comments

I tried using this method, and I actually got a value of undefined instead.
It will be better if every response is clear and precise. Precisely, what is undefined? req.body.itemSKU ? Did you try to console.log(req.body) and see what it contains? Did you remove all the headers (e.g. content-type) like advised?
codesandbox.io/s/musing-paper-rf5vym?file=/pages/index.js see the console.log in both terminal and console.
I made an edit in the original post of what was being returned as undefined. It was req.body.itemSKU. I do not see a major difference in the requests that is in the code sandbox and mine. I use the same method and values for the body.
I was able to resolve the issue, the middleware was fine and was not the cause. Adding the content type headers with the values of application/json resolved the issue. However, I think my original issue was not wrapping itemSKU around curly brackets when using the .stringify function.
|
0

I have faced this same issue if someone is facing the same in 2024. Here is what worked for me:

You have to convert the request to json

export async function POST(request) {
  const formData = await request.json();
  console.log(formData);
  // save to the database or...
  return NextResponse.json({
    message: "Form data submitted successfully!",
    data: data,
  });
}

Credit to this User on GitHub

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.