Search code examples
javascriptreactjsnode.jsjsontypescript

SyntaxError: Unexpected token in JSON.parse - Invalid JSON format being sent in to the Backend


To give you some context:

I am trying to implement a simple Crud with a Client/Server architecture. While doing so I tried making a multi-step form, since a lot of the forms became quite long. But, I soon realized error checking while having a multistep form was harder than a simple one-page form.

In order to check if the Unique values of the form were indeed unused in the DB I created a react-query that will check it for me and display a message if the return message was false, meaning there is a duplicate in the DB.

As I was trying to implement said API endpoint I ran into a curious Error:

The value that is being send into the backend is a JSON string that contains values such as:

{"name": ""xValue""}

Which completely crashes my backend.

I could probably try to do some string manipulation to "clean up" the string before turning it into a JSON string and sending it back to the backend.

But I figured before I patch my error up I should probably address the real problem: the way I am capturing the value. I think...

These are some of the relevant code that I used for this "Unique Checking"

//useState that will hold the value:

  const [carnetValue, setCarnetValue] = useState('');

//React Query and onChange reaction function:

  const { data: isUnique } = useQuery(["checkCarnet", carnetValue], () => apiClient.checkCarnet(carnetValue), {
    enabled: !!carnetValue
  });


  const handleChange = (value: string) => {
    setCarnetValue(value);
  }

//The input itself:

  <input
          type="text"
          className="border border-blue-500 w-full py-1 px-2 font-normal"
          {...register("carnet", { required: "Este campo es necesario", onChange: e => handleChange(e.target.value) })}
        />

//The API Client:

export const checkCarnet = async (carnet: string): Promise<RevisarDato> => {
  console.log(carnet);
  const response = await fetch(`${BASE_API_URL}/api/auth/check-carnet`, {
    method: "POST",
    body: JSON.stringify(carnet),
    headers: {
      "Content-type": "application/json",
    },
  });
  if (!response.ok) {
    throw new Error("Something went wrong");
  }
  const returnData = await response.json();
  return returnData;
};

// In case necessary or relevant this is the Backend Endpoint

export const checkCarnet = async (req: Request, res: Response) => {
  const { carnet } = req.body;
  try {
    const yaExiste = await pool.query(
      "SELECT * FROM Personas WHERE carnet = $1",
      [carnet]
    );
    if (yaExiste.rows.length != 0) {
      return res.status(400).json({ result: false });
    }
    return res.status(200).json({ message: true });
  } catch (error) {
    console.log(error);
    res.status(500).json({ result: "Internal Server Error 500" });
  }
};

This is an example of the displayed Error itself:

SyntaxError: Unexpected token '"', ""asdasda"" is not valid JSON
    at JSON.parse (<anonymous>)

Based on it I can only assume that It has something to do with the way The values are being captured. Maybe it's because I am using both a custom onChange as well as react-hook-form. Maybe some form of string manipulation is always necessary. I am not really sure.

Aside from the error that inspired this post I would also appreciate any feedback or input about the code itself or how to Error Check Uniqueness in Forms.

Edit: Full backend Error Message:

SyntaxError: Unexpected token '"', ""h"" is not valid JSON
    at JSON.parse (<anonymous>)
    at createStrictSyntaxError (C:\Users\Administrador\Documents\GitHub\consultorioDentalv2\backend\node_modules\body-parser\lib\types\json.js:169:10)
    at parse (C:\Users\Administrador\Documents\GitHub\consultorioDentalv2\backend\node_modules\body-parser\lib\types\json.js:86:15)
    at C:\Users\Administrador\Documents\GitHub\consultorioDentalv2\backend\node_modules\body-parser\lib\read.js:128:18   
    at AsyncResource.runInAsyncScope (node:async_hooks:211:14)
    at invokeCallback (C:\Users\Administrador\Documents\GitHub\consultorioDentalv2\backend\node_modules\raw-body\index.js:238:16)
    at done (C:\Users\Administrador\Documents\GitHub\consultorioDentalv2\backend\node_modules\raw-body\index.js:227:7)   
    at IncomingMessage.onEnd (C:\Users\Administrador\Documents\GitHub\consultorioDentalv2\backend\node_modules\raw-body\index.js:287:7)
    at IncomingMessage.emit (node:events:520:28)
    at IncomingMessage.emit (node:domain:488:12)

Solution

  • When sending data to the server, you are only sending a string:

    body: JSON.stringify(carnet)
    

    That's why you are getting a value with double quotes ""asdasda"".

    Considering that on the server side you are retrieving the carnet key, you need to change the request to send a valid JSON:

    body: JSON.stringify({ carnet: carnet })