Why does JSON.parse("foo") fail but JSON.parse(' "foo" ') success? - javascript

When I try to JSON.parse("foo"), I get an Error:
Uncaught SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse (<anonymous>)
at <anonymous>:1:6
But, when I use JSON.parse('"foo"'), I can get the result as expected:
const value = JSON.parse('"foo"');
console.log(value)
So why does this happen?

You can find what makes valid JSON at json.org. JSON can represent null, booleans, numbers, strings, arrays and objects. For strings, they must be enclosed in double quotes.
JSON itself is a string format, so when you specify a string in JSON format, you need:
quotes to tell JavaScript you are specifying a string literal. Those quotes are not part of the string value itself; they are just delimiters.
double-quotes inside that string literal to follow the JSON syntax for the string data type.
So here are some examples of correct arguments for JSON.parse:
JSON.parse("true")
JSON.parse("false")
JSON.parse("null")
JSON.parse("42")
JSON.parse("[13]")
JSON.parse('"hello"')
JSON.parse('{"name": "Mary"}')
But not:
JSON.parse("yes")
JSON.parse("no")
JSON.parse("none")
JSON.parse('hello')
JSON.parse({"name": "Mary"})
Because the argument will be cast to string when it is not, the following will also work, but it is confusing (and useless):
JSON.parse(true)
JSON.parse(false)
JSON.parse(null)
JSON.parse(42)

This happens because JSON.parse() gives a value back by formatting the string given using the syntaxis to declare values in Javascript. Therefore using foo naked would be like casting an undefined variable.
Notice also that the notation uses double quotes " instead of single ones '. That's why JSON.parse('"foo"') works but JSON.parse("'foo'") won't.

Related

Unexpected Token in string version of valid JSON while performing JSON.parse

I am having problem converting a JSON String into Javascript object.
I ran into a few suggestions which said that I should not be using multi-line string but using single line string too did not work.
Snippet: https://jsfiddle.net/ankschoubey/hjh2d3z6/
SyntaxError: Unexpected token F in JSON at position 4536
Because you're including JSON as a JavaScript string value, you'll have to double-up on all the embedded backslash characters because they'll be parsed twice: first when the JavaScript parser reads the overall string constant to create the string value, and then again when you call JSON.parse().
Thus that portion of the string with \" should be \\". That way, the JavaScript string parsing will turn \\" into just \", and that's what will make the JSON parser happy.

Why is JSON.parse so picky with quotes?

Basically, I am trying to create an object like this by providing a string to JSON.parse():
a = {x:1}
// -> Object {x: 1}
Intuitively I tried:
a = JSON.parse('{x:1}')
// -> Uncaught SyntaxError: Unexpected token x
After some fiddling I figured out:
a = JSON.parse('{"x":1}')
// -> Object {x: 1}
But then I accidentally changed the syntax and bonus confusion kicked in:
a = JSON.parse("{'x':1}")
//-> Uncaught SyntaxError: Unexpected token '
So now I am looking for an explanation why
one must to quote the property name
the implementation accepts single quotes, but fails on double quotes
The main reason for confusion seems to be the difference between JSON and JavaScript objects.
JSON (JavaScript Object Notation) is a data format meant to allow data exchange in a simple format. That is the reason why there is one valid syntax only. It makes parsing much easier. You can find more information on the JSON website.
Some notes about JSON:
Keys must be quoted with "
Values might be strings, numbers, objects, arrays, booleans or "null"
String values must be quoted with "
JavaScript objects on the other hand are related to JSON (obviously), but not identical. Valid JSON is also a valid JavaScript object. The other way around, however, is not.
For example:
keys and values can be quoted with " or '
keys do not always have to be quoted
values might be functions or JavaScript objects
As pointed out in the comments, because that's what the JSON spec specifies. The reason AFAIK is that JSON is meant to be a data interchange format (language agnostic). Many languages, even those with hash literals, do not allow unquoted strings as hash table keys.

Why can't Javascript parse this JSON array from a string literal?

What I am trying to do is simple. Parse this array holding json objects into a Javascript array.
var merchantsJson = JSON.parse('[{"id":61693,"name":"Más"},{"id":61690,"name":"\u0027\u0022\u003C/div\u003E"}]');
But the unicode character \u003C seems to be breaking the parser. In the chrome console I see "Uncaught SyntaxError: Unexpected token <"
A little more info. The above is what the code is evaluated to. In reality the code contains a jsp expression.
var merchantsJson = JSON.parse('${jsonArr}');
If I remove the single quotes, there is no issue, but eclipse give me an "missing semicolon" error message. Is it possible to parse the array with the quotes as I am trying to do?
The interpolation of ${jsonArr} is already a JavaScript object. When you wrap it in '${jsonArr}' this turns it into a string and you have to use JSON.parse.
There's no need to make it a string. You can just do var merchantsArray = ${jsonArr}. JSON constructs are already interoperable with JavaScript code.
Because there's an extra " in your string literal that is encoded by \u0022:
> '[{"id":61693,"name":"Más"},{"id":61690,"name":"\u0027\u0022\u003C/div\u003E"}]'
[{"id":61693,"name":"Más"},{"id":61690,"name":"'"</div>"}]
In short, your JSON in the string is invalid. You would need to escape the unicode escape sequences for the quotes in the string literal ("'\u0022</div>"), by using
JSON.parse('[{"id":61693,"name":"Más"},{"id":61690,"name":"\u0027\\u0022\u003C/div\u003E"}]'
// ^
or escape the quote character ("'\"</div>"):
JSON.parse('[{"id":61693,"name":"Más"},{"id":61690,"name":"\u0027\\\u0022\u003C/div\u003E"}]');
// ^^
However, there actually is no need to use JSON at all. Just output a JS array literal into your code:
var merchantsJson = ${jsonArr};
Try to replace \u with \\u. If you don't, JSON parser receives already decoded Unicode, which created polluted JSON.
It's not because of \u003C, rather the \u0022 character is causing the issue, since it's a quotation mark and JavaScript treats it literally ending the string.
You need to escape that character: \\u0022 .
you have to use special character in your JSON string, you can escape it using \ character.
you need to replace \ with \\.
[{\"id\":61693,\"name\":\"Más\"},{\"id\":61690,\"name\":\"\\u0027\\u0022\\u003C/div\\u003E\"}]

JSON.parse not working with double quotes in value

I feel like I have to be missing something simple here. I want to use JSON.parse to convert a string to a JSON object. I've been playing around with this simple example.
JSON.stringify({hi:'"bye"'})
//returns "{"hi":"\"bye\""}"
JSON.parse(JSON.stringify({hi:'"bye"'}))
//returns Object {hi: ""bye""}
JSON.parse("{"hi":"\"bye\""}")
//returns SyntaxError: Unexpected identifier
JSON.parse('{"hi":"\"bye\""}')
//Unexpected token b
My question is what is the difference between passing in the stringify return manually versus passing the return of stringify directly to parse? Mu ultimate goal is to be able to parse a JSON string into a JSON object where the values may contain double quotes.
Thanks for the help.
You have to escape the backslashes and quotation marks when you put the string representation of the object in a string using quotation mark as delimiter:
JSON.parse("{\"hi\":\"\\\"bye\\\"\"}")
When you use apostrophes as string delimiter you don't have to escape quotation marks (but you would have to escape apostrophes if you had any):
JSON.parse('{"hi":"\\"bye\\""}')

Is there any difference in JSON Key when using single quote and double quote?

I ran two pieces of javascript codes in a online JS running platform:Website Link
pets = '{'pet_names':[{"name":"jack"},{"name":"john"},{"name":"joe"}]}';
var arr = JSON.parse(pets);
alert(arr.pet_names[1].name);
Code with double quotes ("pet_names") would be OK but with single quotes('pet_names') would remind a error:"Unexpected identifier"
pets = '{"pet_names":[{"name":"jack"},{"name":"john"},{"name":"joe"}]}';
var arr = JSON.parse(pets);
alert(arr.pet_names[1].name);
So, why do it would happen?
In JSON only double quotes are valid.
You can find the standard on JSON.org
A value can be a string in double quotes, or a number, or true or
false or null, or an object or an array. These structures can be
nested.
In other words, no strings in single quotes.
The first one didn't work because you have a syntax error where you try to define your string literal
you probably wanted
pets = '{\'pet_names\':[{"name":"jack"},{"name":"john"},{"name":"joe"}]}';
notice the quotes are escaped.
Now if you used that string in the json parser you would still get an error(SyntaxError: Unexpected token ') because keys in JSON must be defined with double quotes, using single quotes is valid for defining JavaScript object literals which is separate from JSON.

Categories