Reputation: 7479
What causes this error on the third line?
var products = [{
"name": "Pizza",
"price": "10",
"quantity": "7"
}, {
"name": "Cerveja",
"price": "12",
"quantity": "5"
}, {
"name": "Hamburguer",
"price": "10",
"quantity": "2"
}, {
"name": "Fraldas",
"price": "6",
"quantity": "2"
}];
console.log(products);
var b = JSON.parse(products); //unexpected token o
Open console to view error
Upvotes: 260
Views: 1390480
Reputation: 3293
Let's say you know it's valid JSON, but you’re are still getting this...
In that case, it's likely that there are hidden/special characters in the string from whatever source your getting them. When you paste into a validator, they are lost - but in the string they are still there. Those characters, while invisible, will break JSON.parse()
.
If s
is your raw JSON, then clean it up with:
// Preserve newlines, etc. - use valid JSON
s = s.replace(/\\n/g, "\\n")
.replace(/\\'/g, "\\'")
.replace(/\\"/g, '\\"')
.replace(/\\&/g, "\\&")
.replace(/\\r/g, "\\r")
.replace(/\\t/g, "\\t")
.replace(/\\b/g, "\\b")
.replace(/\\f/g, "\\f");
// Remove non-printable and other non-valid JSON characters
s = s.replace(/[\u0000-\u001F]+/g,"");
var o = JSON.parse(s);
Updated a decade later - the control range is \u0000-\u001F
- fixed...
The formal spec is here: https://www.json.org/json-en.html The reason we preserve the white space and other chars is that the spec allows it and it ensures your white space char is encoded correctly.
Should you accept invalid JSON? It's up to you. But sometimes we got work to do and want to move on.
Upvotes: 168
Reputation: 8055
This is now a JavaScript array of objects, not JSON format. To convert it into JSON format, you need to use a function called JSON.stringify().
JSON.stringify(products)
Upvotes: 0
Reputation: 1607
In my case there are the following character problems in my JSON string:
I have replaced them with other characters or symbols, and then reverted back again from coding.
Upvotes: 0
Reputation: 785
The mistake I was doing was passing null
(unknowingly) into JSON.parse().
So it threw Unexpected token n in JSON at position 0.
But this happens whenever you pass something which is not a JavaScript Object in JSON.parse().
Upvotes: -1
Reputation: 119
It can happen for a lot of reasons, but probably for an invalid character, so you can use JSON.stringify(obj);
that will turn your object into a JSON, but remember that it is a jQuery expression.
Upvotes: 0
Reputation: 8979
The only mistake is you are parsing an already-parsed object, so it's throwing an error. Use this and you will be good to go.
var products = [{
"name": "Pizza",
"price": "10",
"quantity": "7"
}, {
"name": "Cerveja",
"price": "12",
"quantity": "5"
}, {
"name": "Hamburguer",
"price": "10",
"quantity": "2"
}, {
"name": "Fraldas",
"price": "6",
"quantity": "2"
}];
console.log(products[0].name); // Name of item at 0th index
If you want to print the entire JSON content, use JSON.stringify().
Upvotes: 3
Reputation: 633
If there are leading or trailing spaces, it'll be invalid. Trailing and leading spaces can be removed as
mystring = mystring.replace(/^\s+|\s+$/g, "");
Source: JavaScript: trim leading or trailing spaces from a string
Upvotes: 7
Reputation: 1012
The error you are getting, i.e., "unexpected token o", is because JSON is expected, but an object is obtained while parsing. That "o" is the first letter of word "object".
Upvotes: 0
Reputation: 791
Oh man, solutions in all previous answers didn't work for me. I had a similar problem just now. I managed to solve it with wrapping with the quote. See the screenshot. Whoo.
Original:
var products = [{
"name": "Pizza",
"price": "10",
"quantity": "7"
}, {
"name": "Cerveja",
"price": "12",
"quantity": "5"
}, {
"name": "Hamburguer",
"price": "10",
"quantity": "2"
}, {
"name": "Fraldas",
"price": "6",
"quantity": "2"
}];
console.log(products);
var b = JSON.parse(products); //unexpected token o
Upvotes: -1
Reputation: 142
Why do you need JSON.parse? It's already in an array-of-object format.
Better use JSON.stringify as below:
var b = JSON.stringify(products);
Upvotes: -1
Reputation: 87
Here's a function I made based on previous replies: it works on my machine but YMMV.
/**
* @description Converts a string response to an array of objects.
* @param {string} string - The string you want to convert.
* @returns {array} - an array of objects.
*/
function stringToJson(input) {
var result = [];
// Replace leading and trailing [], if present
input = input.replace(/^\[/, '');
input = input.replace(/\]$/, '');
// Change the delimiter to
input = input.replace(/},{/g, '};;;{');
// Preserve newlines, etc. - use valid JSON
//https://stackoverflow.com/questions/14432165/uncaught-syntaxerror-unexpected-token-with-json-parse
input = input.replace(/\\n/g, "\\n")
.replace(/\\'/g, "\\'")
.replace(/\\"/g, '\\"')
.replace(/\\&/g, "\\&")
.replace(/\\r/g, "\\r")
.replace(/\\t/g, "\\t")
.replace(/\\b/g, "\\b")
.replace(/\\f/g, "\\f");
// Remove non-printable and other non-valid JSON characters
input = input.replace(/[\u0000-\u0019]+/g, "");
input = input.split(';;;');
input.forEach(function(element) {
//console.log(JSON.stringify(element));
result.push(JSON.parse(element));
}, this);
return result;
}
Upvotes: 3
Reputation: 89583
Now apparently \r
, \b
, \t
, \f
, etc. aren't the only problematic characters that can give you this error.
Note that some browsers may have additional requirements for the input of JSON.parse
.
Run this test code in your browser:
var arr = [];
for(var x=0; x < 0xffff; ++x){
try{
JSON.parse(String.fromCharCode(0x22, x, 0x22));
}catch(e){
arr.push(x);
}
}
console.log(arr);
Testing on Chrome, I see that it doesn't allow JSON.parse(String.fromCharCode(0x22, x, 0x22));
where x
is 34, 92, or from 0 to 31.
Characters 34 and 92 are the "
and \
characters respectively, and they are usually expected and properly escaped. It's characterss 0 to 31 that would give you problems.
To help with debugging, before you do JSON.parse(input)
, first verify that the input doesn't contain problematic characters:
function VerifyInput(input){
for(var x=0; x<input.length; ++x){
let c = input.charCodeAt(x);
if(c >= 0 && c <= 31){
throw 'problematic character found at position ' + x;
}
}
}
Upvotes: 0
Reputation: 25
[
{
"name": "Pizza",
"price": "10",
"quantity": "7"
},
{
"name": "Cerveja",
"price": "12",
"quantity": "5"
},
{
"name": "Hamburguer",
"price": "10",
"quantity": "2"
},
{
"name": "Fraldas",
"price": "6",
"quantity": "2"
}
]
Here is your perfect JSON content that you can parse.
Upvotes: 0
Reputation: 1197
When you are using the POST or PUT method, make sure to stringify the body part.
I have documented an example here at https://gist.github.com/manju16832003/4a92a2be693a8fda7ca84b58b8fa7154
Upvotes: 0
Reputation: 31
My issue was that I had commented HTML in a PHP callback function via Ajax that was parsing the comments and return invalid JSON.
Once I removed the commented HTML, all was good and the JSON was parsed without any issues.
Upvotes: 1
Reputation: 1230
I found the same issue with JSON.parse(inputString)
.
In my case, the input string is coming from my server page (return of a page method).
I printed the typeof(inputString)
- it was string, but still the error occurs.
I also tried JSON.stringify(inputString)
, but it did not help.
Later I found this to be an issue with the new line operator [\n]
, inside a field value.
I did a replace (with some other character, put the new line back after parse) and everything was working fine.
Upvotes: 33
Reputation: 14927
products is an array which can be used directly:
var i, j;
for(i=0; i<products.length; i++)
for(j in products[i])
console.log("property name: " + j, "value: " + products[i][j]);
Upvotes: 0
Reputation: 33624
It seems you want to stringify the object, not parse. So do this:
JSON.stringify(products);
The reason for the error is that JSON.parse()
expects a String
value and products
is an Array
.
Note: I think it attempts json.parse('[object Array]')
which complains it didn't expect token o
after [
.
Upvotes: 82
Reputation: 5519
You should validate your JSON string here.
A valid JSON string must have double quotes around the keys:
JSON.parse({"u1":1000,"u2":1100}) // will be ok
If there are no quotes, it will cause an error:
JSON.parse({u1:1000,u2:1100})
// error Uncaught SyntaxError: Unexpected token u in JSON at position 2
Using single quotes will also cause an error:
JSON.parse({'u1':1000,'u2':1100})
// error Uncaught SyntaxError: Unexpected token ' in JSON at position 1
Upvotes: 21
Reputation: 496
JSON.parse is waiting for a String in parameter. You need to stringify your JSON object to solve the problem.
products = [{"name":"Pizza","price":"10","quantity":"7"}, {"name":"Cerveja","price":"12","quantity":"5"}, {"name":"Hamburguer","price":"10","quantity":"2"}, {"name":"Fraldas","price":"6","quantity":"2"}];
console.log(products);
var b = JSON.parse(JSON.stringify(products)); //solves the problem
Upvotes: 38
Reputation: 22255
One other gotcha that can result in "SyntaxError: Unexpected token"
exception when calling JSON.parse()
is using any of the following in the string values:
New-line characters.
Tabs (yes, tabs that you can produce with the Tab key!)
Any stand-alone slash \
(but for some reason not /
, at least not on Chrome.)
(For a full list see the String section here.)
For instance the following will get you this exception:
{
"msg" : {
"message": "It cannot
contain a new-line",
"description": "Some discription with a tabbed space is also bad",
"value": "It cannot have 3\4 un-escaped"
}
}
So it should be changed to:
{
"msg" : {
"message": "It cannot\ncontain a new-line",
"description": "Some discription with a\t\ttabbed space",
"value": "It cannot have 3\\4 un-escaped"
}
}
Which, I should say, makes it quite unreadable in JSON-only format with larger amount of text.
Upvotes: 2
Reputation: 19
Use eval
. It takes JavaScript expression/code as string and evaluates/executes it.
eval(inputString);
Upvotes: -26
Reputation: 887195
products
is an object. (creating from an object literal)
JSON.parse()
is used to convert a string containing JSON notation into a Javascript object.
Your code turns the object into a string (by calling .toString()
) in order to try to parse it as JSON text.
The default .toString()
returns "[object Object]"
, which is not valid JSON; hence the error.
Upvotes: 268
Reputation: 8524
products = [{"name":"Pizza","price":"10","quantity":"7"}, {"name":"Cerveja","price":"12","quantity":"5"}, {"name":"Hamburguer","price":"10","quantity":"2"}, {"name":"Fraldas","price":"6","quantity":"2"}];
change to
products = '[{"name":"Pizza","price":"10","quantity":"7"}, {"name":"Cerveja","price":"12","quantity":"5"}, {"name":"Hamburguer","price":"10","quantity":"2"}, {"name":"Fraldas","price":"6","quantity":"2"}]';
Upvotes: 14