Problem
I was making an AJAX call to the backend from the frontend JavaScript code, which was supposed to return a JSON response. But while parsing the response with JSON.parse(data), I got this error:
Uncaught SyntaxError: Unexpected token o in JSON at position 1
Reason
The reason is simple:
The data you are trying to parse in JavaScript is already a JavaScript Object. When the JSON.parse(data) tries to parse a string to JSON, it expects a string parameter. And as it is getting a JavaScript object already, so JavaScript can not parse it and generate JSON from it.
As it is already an object, you don’t need to parse it.
You can regenerate the same error by the following JavaScript code:
JSON.parse(new Object()); // this will throw "Uncaught SyntaxError: Unexpected token o in JSON at position 1"
As the JSON.parse is trying to convert its argument to a string like the below, which returns ‘[object Object]’.
new Object().toString();
// This will return '[object Object]'
So in turn the JSON.parse statement becomes like this:
JSON.parse('[object Object]');
Or just try with a JavaScript object directly.
const serverList = {server_1: 2, server_2: 4};
const jsonData = JSON.parse(serverList); // throws error as serverList.toString() is '[object Object]'
That’s why JSON.parse is getting “o” at position 1. And as it does not represent a valid JSON, so the error is thrown.
You can check much more details about JSON.parse implementation from the link: https://tc39.es/ecma262/multipage/structured-data.html#sec-json.parse
Let’s look at a few approaches to solve the error, that can be used based on your specific use case.
Solutions
Use any of the following solutions. Solution #4 is the best one as it handles all the cases.
If just removing the parsing works for you, then that is fine too.
Solution #1: Remove the JSON.parse
The first thing you can try is just removing that JSON.parse (or any parsing method that you are using).
As you already have an Object, no need to parse. So removing the parsing should solve the problem.
Solution #2: Stringify first and then Parse
If in your case it is necessary to use JSON parsing, then stringify the object first using JSON.stringify(data) and then parse using JSON.parse. like below:
JSON.parse(JSON.stringify(data));
This will eliminate the error.
Solution #3: Use try/catch
In some cases, if you are not sure about the data. Say sometimes it is a string, sometimes it is an object. Then use try/catch to handle that.
let dataObj = null;
try {
dataObj = JSON.parse(data); // Try to parse first
} catch (e) {
// If it fails then it means, we already have an object
dataObj = data;
}
Solution #4: Check the type and decide
If you are not sure about the response, then check the type and decide how to handle it.
Use a checking like the one below.
const parseJSON = (data) => {
if (!data) return {}; // If data is blank then return blank object
if (typeof data === 'object') return data; // If data is already an object then just return that. No processing required.
if (typeof data === 'string') return JSON.parse(data); // If data is a string then parse and return that.
return {}; // If data is something else, then return blank object
}
Either create a separate function or just use the checking where needed.