22

I tried this simple JavaScript code:

eval('{"Topics":["toto","tata","titi"]}')

In the Chrome console, for example, this returns

SyntaxError: Unexpected token :

I tried the JSON on JSONLint and it's valid.

Do you see the bug?

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
Tuizi
  • 1,643
  • 4
  • 22
  • 34

8 Answers8

52

You have to write like this

eval('('+stringJson+')' );

to convert an string to Object

Hope I help!

Jonas Sourlier
  • 13,684
  • 16
  • 77
  • 148
Martin Varta
  • 766
  • 1
  • 7
  • 10
30

Because eval does not force an expression context and the string provided is an invalid JavaScript program, thus the first three tokens (and how they are looked at) are:

{            // <-- beginning of a block, and NOT an Object literal
"Topics"     // <-- string value, okay (note this is NOT a label)
:            // <-- huh? expecting ";" or "}" or an operator, etc.

Happy coding.

  • may I ask you why eval('function(){}') throws an exception too ? – BiAiB Jan 09 '13 at 17:38
  • 4
    @BiAiB For the same reason as above :) The contents of `eval` run in a *statement* context and thus it is taken as a FunctionDeclaration grammar construct. The error generated by that is "SyntaxError: function statement requires a name". Either give it a name (`eval('function f(){}'); f()`) or force it into a FunctionExpression construct (`f = eval('(function(){alert("hi")})'); f()`). See http://es5.github.com/x13.html –  Jan 09 '13 at 20:53
  • thanks! the tricky part to me was because strings like '3' are correctly evaluated, and not 'function(){}'. The second cannot be evaluated as an ExpressionStatement: `an ExpressionStatement cannot start with the function keyword because that might make it ambiguous with a FunctionDeclaration` (http://es5.github.com/x12.html#x12.4) – BiAiB Jan 10 '13 at 10:54
14

FWIW, use JSON.parse instead. Safer than eval.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
Jonathan M
  • 17,145
  • 9
  • 58
  • 91
9

Number one: Do not use eval.

Number two. Only use eval to make something, well be evaluated. Like for example:

eval('var topics = {"Topics":["toto","tata","titi"]}');
Naftali
  • 144,921
  • 39
  • 244
  • 303
4

USE:

function evalJson(jsArray){ eval("function x(){ return "+ jsArray +"; }"); return x(); }

var yourJson =evalJson('{"Topics":["toto","tata","titi"]}');

console.log(yourJson.Topics[1]); // print 'tata''
competent_tech
  • 44,465
  • 11
  • 90
  • 113
Pica Mio
  • 51
  • 2
4

Because that's evaluating an object. eval() requires you to pass in syntactically valid javascript, and all you're doing is passing in a bare object. The call should be more like:

eval('var x = {"Topics":etc...}');
Marc B
  • 356,200
  • 43
  • 426
  • 500
0

if you are using JQuery use the function $.parseJSON(), worked for me, had the same problem

Mark E
  • 3,403
  • 2
  • 22
  • 36
0

if you want to make an array use the below code

var jsonObject = eval('(' +"["+ response + "]"+')');