[javascript] Convert object string to JSON

How can I convert a string that describes an object into a JSON string using JavaScript (or jQuery)?

e.g: Convert this (NOT a valid JSON string):

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"

into this:

str = '{ "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] }'

I would love to avoid using eval() if possible.

This question is related to javascript json object

The answer is


Your string is not valid JSON, so JSON.parse (or jQuery's $.parseJSON) won't work.

One way would be to use eval to "parse" the "invalid" JSON, and then stringify it to "convert" it to valid JSON.

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"
str = JSON.stringify(eval('('+str+')'));

I suggest instead of trying to "fix" your invalid JSON, you start with valid JSON in the first place. How is str being generated, it should be fixed there, before it's generated, not after.

EDIT: You said (in the comments) this string is stored in a data attribute:

<div data-object="{hello:'world'}"></div>

I suggest you fix it here, so it can just be JSON.parsed. First, both they keys and values need to be quoted in double quotes. It should look like (single quoted attributes in HTML are valid):

<div data-object='{"hello":"world"}'></div>

Now, you can just use JSON.parse (or jQuery's $.parseJSON).

var str = '{"hello":"world"}';
var obj = JSON.parse(str);

Just for the quirks of it, you can convert your string via babel-standalone

_x000D_
_x000D_
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";_x000D_
_x000D_
function toJSON() {_x000D_
  return {_x000D_
    visitor: {_x000D_
      Identifier(path) {_x000D_
        path.node.name = '"' + path.node.name + '"'_x000D_
      },_x000D_
      StringLiteral(path) {_x000D_
        delete path.node.extra_x000D_
      }_x000D_
    }_x000D_
  }_x000D_
}_x000D_
Babel.registerPlugin('toJSON', toJSON);_x000D_
var parsed = Babel.transform('(' + str + ')', {_x000D_
  plugins: ['toJSON']_x000D_
});_x000D_
var json = parsed.code.slice(1, -2)_x000D_
console.log(JSON.parse(json))
_x000D_
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
_x000D_
_x000D_
_x000D_


A solution with one regex and not using eval:

str.replace(/([\s\S]*?)(')(.+?)(')([\s\S]*?)/g, "$1\"$3\"$5")

This I believe should work for multiple lines and all possible occurrences (/g flag) of single-quote 'string' replaced with double-quote "string".


var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
var json = JSON.stringify(eval("(" + str + ")"));

There's a much simpler way to accomplish this feat, just hijack the onclick attribute of a dummy element to force a return of your string as a JavaScript object:

var jsonify = (function(div){
  return function(json){
    div.setAttribute('onclick', 'this.__json__ = ' + json);
    div.click();
    return div.__json__;
  }
})(document.createElement('div'));

// Let's say you had a string like '{ one: 1 }' (malformed, a key without quotes)
// jsonify('{ one: 1 }') will output a good ol' JS object ;)

Here's a demo: http://codepen.io/csuwldcat/pen/dfzsu (open your console)


Use with caution (because of eval()):

function strToJson(str) {
  eval("var x = " + str + ";");
  return JSON.stringify(x);
}

call as:

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
alert( strToJson(str) );

I hope this little function converts invalid JSON string to valid one.

function JSONize(str) {
  return str
    // wrap keys without quote with valid double quote
    .replace(/([\$\w]+)\s*:/g, function(_, $1){return '"'+$1+'":'})    
    // replacing single quote wrapped ones to double quote 
    .replace(/'([^']+)'/g, function(_, $1){return '"'+$1+'"'})         
}

Result

let invalidJSON = "{ hello: 'world',foo:1,  bar  : '2', foo1: 1, _bar : 2, $2: 3, 'xxx': 5, \"fuz\": 4, places: ['Africa', 'America', 'Asia', 'Australia'] }"
JSON.parse(invalidJSON) 
//Result: Uncaught SyntaxError: Unexpected token h VM1058:2
JSON.parse(JSONize(invalidJSON)) 
//Result: Object {hello: "world", foo: 1, bar: "2", foo1: 1, _bar: 2…}

I put my answer for someone who are interested in this old thread.

I created the HTML5 data-* parser for jQuery plugin and demo which convert a malformed JSON string into a JavaScript object without using eval().

It can pass the HTML5 data-* attributes bellow:

<div data-object='{"hello":"world"}'></div>
<div data-object="{hello:'world'}"></div>
<div data-object="hello:world"></div>

into the object:

{
    hello: "world"
}

Disclaimer: don't try this at home, or for anything that requires other devs taking you seriously:

JSON.stringify(eval('(' + str + ')'));

There, I did it.
Try not to do it tho, eval is BAD for you. As told above, use Crockford's JSON shim for older browsers (IE7 and under)

This method requires your string to be valid javascript, which will be converted to a javascript object that can then be serialized to JSON.

edit: fixed as Rocket suggested.


Using new Function() is better than eval, but still should only be used with safe input.

const parseJSON = obj => Function('"use strict";return (' + obj + ')')();

console.log(parseJSON("{a:(4-1), b:function(){}, c:new Date()}"))
// outputs: Object { a: 3, b: b(), c: Date 2019-06-05T09:55:11.777Z }

Sources: MDN, 2ality


jQuery.parseJSON

str = jQuery.parseJSON(str)

Edit. This is provided you have a valid JSON string


You need to use "eval" then JSON.stringify then JSON.parse to the result.

 var errorString= "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
 var jsonValidString = JSON.stringify(eval("(" + errorString+ ")"));
 var JSONObj=JSON.parse(jsonValidString);

enter image description here


Maybe you have to try this:

str = jQuery.parseJSON(str)

This will also work

let str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"
let json = JSON.stringify(eval("("+ str +")"));

Your best and safest bet would be JSON5 – JSON for Humans. It is created specifically for that use case.

_x000D_
_x000D_
const result = JSON5.parse("{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }");_x000D_
_x000D_
console.log(JSON.stringify(result));
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/json5/0.5.1/json5.min.js"></script>
_x000D_
_x000D_
_x000D_


var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }" var fStr = str .replace(/([A-z]*)(:)/g, '"$1":') .replace(/'/g, "\"")

console.log(JSON.parse(fStr))enter image description here

Sorry I am on my phone, here is a pic.


Use simple code in the link below :

http://msdn.microsoft.com/es-es/library/ie/cc836466%28v=vs.94%29.aspx

var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';
var contact = JSON.parse(jsontext);

and reverse

var str = JSON.stringify(arr);

For your simple example above, you can do this using 2 simple regex replaces:

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
str.replace(/(\w+):/g, '"$1":').replace(/'/g, '"');
 => '{ "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] }'

Big caveat: This naive approach assumes that the object has no strings containing a ' or : character. For example, I can't think of a good way to convert the following object-string to JSON without using eval:

"{ hello: 'world', places: [\"America: The Progressive's Nightmare\"] }"

Douglas Crockford has a converter, but I'm not sure it will help with bad JSON to good JSON.

https://github.com/douglascrockford/JSON-js


You have to write round brackets, because without them eval will consider code inside curly brackets as block of commands.

var i = eval("({ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] })");

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to json

Use NSInteger as array index Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) HTTP POST with Json on Body - Flutter/Dart Importing json file in TypeScript json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 190) Angular 5 Service to read local .json file How to import JSON File into a TypeScript file? Use Async/Await with Axios in React.js Uncaught SyntaxError: Unexpected token u in JSON at position 0 how to remove json object key and value.?

Examples related to object

How to update an "array of objects" with Firestore? how to remove json object key and value.? Cast object to interface in TypeScript Angular 4 default radio button checked by default How to use Object.values with typescript? How to map an array of objects in React How to group an array of objects by key push object into array Add property to an array of objects access key and value of object using *ngFor