Unexpected JSON end causes issue with DELETE request in Next.js version 13

I am currently working on a web app using Next 13 and I have a route.ts file located in the api folder. This file contains two different methods, POST and DELETE.

While both methods successfully receive the request, I am facing an issue with JSON parsing the body of the DELETE request. Strangely, it works for the POST method but not for the DELETE method, even though I am following the same steps.

I have checked the request in the 'Network' tab of the developer tools and the payload seems to be fine. Can anyone help me figure out what I might be missing?

Here is the Error message I am encountering:

SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at NextRequest.json (node:internal/deps/undici/undici:6160:23)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async DELETE (webpack-internal:///(sc_server)/./app/api/workPlace/route.ts:35:22)
    at async eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:242:37)

The JSON structure of the DELETE request body should consist of an array of strings.

This is how the frontend code looks like:

export async function fetchRemoveWorkPlaces(ids: string[]) {
    const data = { ids: ids }
    const response = await fetch(
        '/api/workPlace', 
        {
            method: 'DELETE',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(data)
        }
    )
  }

Below is the implementation of the route.ts on the server side:

export async function POST(req: Request, res: NextResponse , context: {}) {
    
    try {
        const body: any = await req.json()
        const response = await workPlaceDao.addWorkPlace(body)

        return NextResponse.json(
            {
                success: true,
                workPlace: response
            }, 
            { status: 200 })
    } catch (e) {
        console.log('Error occurred while Add Work Place Request');
        console.log(e);
        return NextResponse.json({success: false}, { status: 500 })
    }
}
export async function DELETE(req: Request, res: NextResponse , context: {}) {

    try {
        const body: any = await req.json()
        const response = await workPlaceDao.deleteWorkPlace(body.ids)

        return NextResponse.json(
            {
                success: true,
            }, 
            { status: 200 })
    } catch (e) {
        console.log('Error occurred trying to delete Work Places');
        console.log(e);
        return NextResponse.json({success: false}, { status: 500 })
    }
}

Answer №1

There is a known issue that has been acknowledged, but progress towards a solution has been minimal.

  • To learn more about this bug, visit: https://github.com/vercel/next.js/issues/53882

  • A temporary fix involves utilizing traditional methods by alias-ing. Currently, the most effective options are GET and POST requests.

  • If you need your hook to communicate with the REST API

export async function fetchRemoveWorkPlaces(ids: string[]) {
    const data = { ids: ids }
    const response = await fetch(
        '/api/workPlace2',  // Modify this accordingly
        {
            method: 'DELETE',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(data)
        }
    )
  }

subsequently integrate the delete code into the newly implemented "POST" request

export async function POST(req: Request, res: NextResponse , context: {}) {
    
   try {
        const body: any = await req.json()
        const response = await workPlaceDao.deleteWorkPlace(body.ids)

        return NextResponse.json(
            {
                success: true,
            }, 
            { status: 200 })
    } catch (e) {
        console.log('Error occurred trying to delete Work Places');
        console.log(e);
        return NextResponse.json({success: false}, { status: 500 })
    }
}

Answer №2

When making DELETE requests, it's common for them not to include a body. Instead, IDs can be sent as query parameters on the frontend:

export async function fetchDeleteWorkplaces(ids: string[]) {
    const response = await fetch(
        `/api/workplace?ids=${JSON.stringify(ids)}`, 
        {
            method: 'DELETE',
            headers: {'Content-Type': 'application/json'},
        }
    );
}

On the server side, you can easily access the query parameters without having to parse the request body:

export async function handleDeleteRequest(req: Request, res: NextResponse , context: {}) {

    try {
        const ids: string[] = JSON.parse(req.query.ids as string); // Parsing the query parameter

        const response = await workPlaceDao.deleteWorkPlaces(ids);

        return NextResponse.json(
            {
                success: true,
            }, 
            { status: 200 });
    } catch (e) {
        console.log('An error occurred while trying to delete Work Places');
        console.log(e);
        return NextResponse.json({success: false}, { status: 500 });
    }
}

Answer №3

When working with NextJs:

Use axios to execute a delete request on the '/api/item' endpoint

In the backend of your NextJs project: /api/item/route.ts

Create an async function DELETE that captures the Request object and extracts the id from the URL

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering an issue in Next.js when using getStaticProps: reading 'map' of undefined properties

The Image above shows the error and the code I have attempted.Server Error TypeError: Cannot read properties of undefined (reading 'map') This particular error occurred during the page generation process. Any console logs will appear in the term ...

NextJS API routes consistently provide a status code of 200 upon execution

I am new to the concepts of Next.js, and I recently encountered an issue while attempting to fetch data from an API. The API is designed to check if a user session exists (i.e., if the user is logged in) and then returns a JSON response through a GET reque ...

Using RxJS with Angular to intercept the valueChanges of a FormControl prior to subscribing

I decided to create a new observable using the values emitted by the FormControls.valueChanges observable. This creation of the observable takes place within the ngOnInit method in the following manner: ngOnInit(): void { this.myObservable$ = combine ...

Using @material-ui/core/useScrollTrigger in a Next.js application: a step-by-step guide

I have been researching the Material-UI documentation for useScrollTrigger and attempting to implement it in Next.js to replicate the Elevate App Bar. https://material-ui.com/components/app-bar/#usescrolltrigger-options-trigger import React from "react"; ...

Tips for typing a destructured object key in TypeScript

Assuming I have a query parameter from the router in my Next.js app const { query: { id }, } = useRouter(); The value of { id } is currently string | string[] | undefined. I want to send it as a parameter to another function, and I am certain that ...

Is there a way to retrieve a data type from a class in TypeScript?

Within my code, there exists a class: class Person { name: string; age: number; gender: string; constructor(params: any){ this.name = params.name; this.age = params.age; this.gender = params.gender; } } My question is how ca ...

Facing issues with Angular 13 migration: Schema validation encountered errors stating that the data path "/error" needs to be a string

Currently in the process of migrating from Angular 8 to 13 and encountering an issue. I have been following the guidelines outlined on https://update.angular.io/, however, every time I attempt to build certain custom libraries from my application root fold ...

What is the best way to instantiate objects, arrays, and object-arrays in an Angular service class?

How can I nest an object within another object and then include it in an array of objects inside an Angular service class? I need to enable two-way binding in my form, so I must pass a variable from the service class to the HTML template. trainer.service. ...

Troubles with Jest tests are encountered when using ts-jest in an ES2020/ESNEXT TypeScript project

Currently, I am working on a VueJS project that utilizes ViteJS for transpilation, which is functioning properly. However, when Jest testing is involved alongside ts-jest, the following Jest configuration is used: jest.config.ts import { resolve } from &q ...

What is the reason for requiring that the value type in a map must be uniform?

When using TypeScript, I expect the map type to be either a number or string, but unfortunately, an error is being reported. Click here for the Playground const map: Map<string, string | number> = new Map([ [ '1', &apo ...

Designing a Tombstone with TypeScript

In TypeScript, I have certain values that are only necessary within the type system and not at runtime. I am seeking a way to void these values without losing their type information. The function bury illustrated below is intended to replace the actual v ...

What is the best method for retrieving system environment variables in Next.js?

For my Next.JS app, I utilized environment variables. These variables are set as the system's environment variables since it is a dockerized nextjs app. # in terminal echo $NEXT_PUBLIC_KEY_NAME # >> value of key Surprisingly, process.env.NEXT_P ...

The term "define" is not recognized when constructing a Next.js application

Currently, I am working with Next version 10.0.1 and React 17.0.2. While attempting to build my Next app, I encountered the following error: ReferenceError: define is not defined at Object.<anonymous> (/Users/username/Desktop/project/node_module ...

Combining TypeScript into HTML resulted in an error: Uncaught ReferenceError clickbutton is not defined

Attempting to create a basic CRUD frontend without the use of any frameworks. I am encountering an issue when trying to include a TypeScript file (index.ts) in my index.html, as the functions called within it are showing as undefined. I understand that bro ...

Utilizing Material UI and TypeScript to effectively pass custom properties to styled components

Currently, I am utilizing TypeScript(v4.2.3) along with Material UI(v4.11.3), and my objective is to pass custom props to the styled component. import React from 'react'; import { IconButton, styled, } from '@material-ui/core'; con ...

Issues are arising with Angular Form where the FormControl is not being properly set up for the first field in my form

After grappling with this issue for several weeks, I am still unable to pinpoint the cause. (Angular version: 16.1.4) The form component is populated using a BehaviorSubject, and although the console prints out the correct values for both the form and dat ...

The current issue with the Next.js 13 beta application is that the nested layout directory does not scroll to the top when the route is

Check out the live demo here. Ensure to scroll down and click on a link in the header. In my project, I have two files named layout.tsx: one in the src directory and another in the (public) directory with a sticky <Header /> component. The expected ...

Issue: React-Firebase-Hooks failing to retrieve dataHaving trouble with React-F

I've been utilizing the React-Firebase-Hooks package in my project, but I'm encountering some difficulties with its usage. In the code snippet below, the user.data().username is displayed correctly. However, when I try to use it within useState, ...

Looking to execute multiple programs simultaneously within the prestart script in the package.json file, and bypass any exit error codes

I need to run yarn tsc and yarn lint during every yarn start to identify any code errors. This is how my scripts property is set up: "scripts": { "start": "expo start", "android": "expo start --android" ...

Is there a way to implement a pipe function in TypeScript?

Introducing a unique pipe function implemented in plain JavaScript: const customPipe = (f, ...fs) => x => f === undefined ? x : customPipe(...fs)(f(x)) const exampleFunction = customPipe( x => x + 1, x => `wow ${x * 2} this is an amaz ...