2

I couldn't get JSON.parse to convert a string to an object and I found this code which solves my problem - however, I can't figure out how it works. I would be grateful if someone can explain (to a JavaScript beginner) what's going on in the 3rd line. Thank you.

var str, obj;
str = "{src:'img/testimage.jpg', coord:{x:17, y:39}, width:200, height:200}";
obj = new Function('return '+str)();
Fred
  • 73
  • 2
  • 8
  • Weird, never seen this practice before. – DontVoteMeDown Oct 26 '15 at 19:44
  • 9
    That last line is another way to spell `eval` - it should never be needed to parse JSON. The problem you're having is that you need to put the JSON keys in quotes in order to use JSON.parse. – nneonneo Oct 26 '15 at 19:46
  • 1
    JSON.parse was not working because your keys are not enclosed in `""` quotes – vinayakj Oct 26 '15 at 19:46
  • The (string) values need to be in double quotes too. – gen_Eric Oct 26 '15 at 19:47
  • 2
    @MaxMastalerz because it's not a valid JSON string. – halfzebra Oct 26 '15 at 19:47
  • 2
    Where is that string coming from? – Pointy Oct 26 '15 at 19:49
  • 1
    Incrementing, to see how a valid JSON would be, you can stringify the result: `JSON.stringify(f())`, yields `"{"src":"img/testimage.jpg","coord":{"x":17,"y":39},"width":200,"height":200}"`. – Kriggs Oct 26 '15 at 19:51
  • @Pointy the string is coming from a textarea in an html doc. The user types in an object (with the standard object syntax) and then I am trying to turn this into a usable object. I'm using `document.getElementById` which returns the user's input in the string format as above. – Fred Oct 27 '15 at 09:58

4 Answers4

3

It creates a function with your string as the body of the function, but return in front of it and then it runs that function. The outcome is to evaluate your string and return the object that it creates.

It is basically the same as doing this, but you create the function programmatically:

function f() {
   return {src:'img/testimage.jpg', coord:{x:17, y:39}, width:200, height:200};
}

obj = f();

FYI, JSON.parse() does not work because your string is valid Javascript, but is not valid JSON. To make it valid JSON, all property names must also be quoted.


This would be valid JSON:

var str = '{"src":"img/testimage.jpg", "coord":{"x":17, "y":39}, "width":200, "height":200}'
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Thank you! That explains it. I understand now that I shouldn't have been trying to use JSON.parse to shoehorn the string into an object. Is the `function f() { return {src:'img/testimage.jpg', coord:{x:17, y:39}, width:200, height:200}; }` approach safe to use? It sounds like the approach I have used above, which uses `eval`, is not safe? – Fred Oct 27 '15 at 10:05
  • @Fred it's safe so long as you're OK with the fact that the user can type in literally any valid JavaScript expression. – Pointy Oct 27 '15 at 13:28
0

You can use the debugger window to see what is going on. That last line simply returns an object.

enter image description here

9ers Rule
  • 164
  • 1
  • 1
  • 14
0

couldn't get JSON.parse to convert a string to an object

Could try to use .replace() to replace single quotes ' with double quotes " , add double quotes to property names before ":" at input string , then call JSON.parse() on resulting string

var str = "{src:'img/testimage.jpg', coord:{x:17, y:39}, width:200, height:200}";
var obj = str.replace(/'/g, "\"").replace(/(\w+)(?=:)/g, "\"$1\"");
console.log(JSON.parse(obj))
guest271314
  • 1
  • 15
  • 104
  • 177
0

For completeness, note that if there's something you perceive as JSON that you simply want to hard-code into your JavaScript source, there's no need for any JSON parsing at all:

var obj = {src:'img/testimage.jpg', coord:{x:17, y:39}, width:200, height:200};

is fine.

Pointy
  • 405,095
  • 59
  • 585
  • 614