The JSON.parse()
static method provides a function for parsing a string and constructing the object or JavaScript value that the string represents. Usually, the JSON.parse()
method is used when transforming responses received from servers that are JSON in nature but encoded as strings.
In most instances, the JSON.parse()
method is robust enough to deal with improperly formatted values. However, when presented with an empty string (or a non-string value), it will throw the error below:
Uncaught SyntaxError: Unexpected end of JSON input
There are several reasons why using JSON.parse()
may result in the error above. We’ll address some of the common reasons.
If you are using JSON.parse()
to convert the response from an API into an object you can work with, it’s important to verify that the response contains information that can be parsed.
In the following example, it’s possible that our API call doesn’t return a value (or hasn’t yet finished returning a value). As such, using JSON.parse()
results in an error:
const Posts = () => { const [data, setData] = useState([]); useEffect(() => { async function fetchData() { const storedData = (await fetch("/api/posts").then((response) => response.data)) || []; setData(storedData); } fetchData(); }, []); const postsData = JSON.parse(data) || []; };
In this scenario, when JSON.parse()
is called, the value of data
can equal []
which is not a string value and results in the error.
We can improve this code to prevent encountering the Unexpected end of JSON input
error by parsing the data as it is fetched, rather than parsing it after fetching and risking it being equal to [].
const Posts = () => { const [data, setData] = useState([]); useEffect(() => { async function fetchData() { const storedData = (await fetch("/api/posts").then((response) => JSON.parse(response.data) )) || []; setData(storedData); } fetchData(); }, []); };
If you store data in local storage that you later need to parse as JSON and use in your application, you might encounter this error when calling JSON.parse()
.
Similarly to the network request example above, the following code can result in an error when the information retrieved from local storage is not present.
const Posts = () => { const [data, setData] = useState([]); useEffect(() => { const storedData = window.localStorage.getItem("Post") || []; setData(storedData); }, []) const jobData = JSON.parse(data) || []; };
When data
is set to []
, we get the Unexpected end of JSON input
error. This can be resolved with the following refactoring:
const Posts = () => { const [data, setData] = useState([]); useEffect(() => { const storedData = window.localStorage.getItem("Post"); if (storedData) { try { const parsedData = JSON.parse(storedData); if (Array.isArray(parsedData)) { setData(parsedData); } else { setData([]); } } catch (error) { setData([]); } } }, []); };
We first check whether the data we want to parse exists in local storage before calling JSON.parse()
. This ensures that we don’t call the method with invalid data.
Although the JSON.parse()
function is designed to accept string input, the string input must be valid JSON. This means that an empty string will result in an error, like this:
const myString = ""; const parsedString = JSON.parse(myString); // This will throw an exception
To fix this error, you can check if the string is empty before using it in the JSON.parse()
method.
In some scenarios, it is hard to avoid malformed input being used in JSON.parse()
. To cater for these cases, it is a good idea to wrap the method call in a try / catch
block so that you can properly handle the exception. Below is an example where we wrap the JSON.parse()
method invocation in a try / catch
block:
function ParseData(inputData) { try { var data = JSON.parse(inputData); return data; } catch (e) { // properly handle the error when the input is not a valid JSON string ... } }
If you encounter this error and you’re not explicitly using the JSON.parse()
method, you may have a formatting error in your code.
In the following example, we’ve forgotten to add the closing brace }
to our function. This results in the SyntaxError: Unexpected end of input
error.
function divide(a, b) { return a / b;
Avoiding errors when using JSON.parse()
involves validating whether the input is correct (a valid JSON string). The official documentation for the method provides several examples of correct usage and the associated results.
Get actionable, code-level insights to resolve JavaScript performance bottlenecks and errors.
Create a free Sentry account
Create a JavaScript project and note your DSN
Grab the Sentry JavaScript SDK
<script src="https://browser.sentry-cdn.com/7.112.2/bundle.min.js"></script>
Sentry.init({ dsn: 'https://<key>@sentry.io/<project>' });
Loved by over 4 million developers and more than 90,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.