Javascript Convert String to Array of Objects
Asked Answered
P

2

15

I have a NodeJS App that accepts a a string (uploaded input!) I have No Control over the input I am merely building a REST Service to Processes the data.

That string is meant to be an Array of JSON Objects that I can then loop through to extract each element ...

I'm receiving the following (as a string):

[
  {Name: 'Jane',
       Id: '005b0000000MGa7AAG'},
  {Name: 'Tom',
       Id: '005b0000000MGa7AAF'}
]

When I try to JSON.parse this I get

SyntaxError: Unexpected token N

Understandably so, because I know this is Invalid JSON

whereas This next string is valid JSON and passes http://jsonlint.com/:

[
    {"Name": "Jack",
        "Id": "005b0000000MGa7AAA"},
    {"Name": "Jill",
        "Id": "005b0000000MGa7AAB"}
]

My question is: How can I accept the first input and parse it to allow:

parsed[0]['Name'] == 'Jane'
>> true

My first instinct is to string replace the keys (e.g. Name to "Name") and then try parsing it. But if anyone else has a solution, I'd be grateful.

Pentothal answered 25/4, 2013 at 11:44 Comment(3)
The user has to type the JSON?Pledgee
the first one is not in the json formatEndothecium
Hi @ExplosionPills I should have clarified that its a web-service that accepts JSON. The uploaded string is not hand-typed by the user instead it is generated by a JAVA App (out of my control) and sent to my NodeJS app for processing. They are sending me inValid JSON... :-(Pentothal
G
18

You can do this with a bit of Regex replacing:

var json = "[ {Name: 'Jane', Id: '005b0000000MGa7AAG'}, {Name: 'Tom', Id: '005b0000000MGa7AAF'} ]";

var newJson = json.replace(/([a-zA-Z0-9]+?):/g, '"$1":');
newJson = newJson.replace(/'/g, '"');

var data = JSON.parse(newJson);

alert(data[0]["Name"]);

First of all we wrap the propertie names with quotes, then we replace the single-quotes with double-quotes. This is enough to make it valid JSON which can then be parsed.

Here is a working example


NOTE: Using RegEx in general for things like this is not ideal, and this solution will only work under specific circumstances (like this example). As mentioned in comments, one problem would be if the data values contained a colon :

With that in mind, this is a more reliable solution:

var json = $("div").html();

var newJson = json.replace(/'/g, '"');

newJson = newJson.replace(/([^"]+)|("[^"]+")/g, function($0, $1, $2) {
    if ($1) {
        return $1.replace(/([a-zA-Z0-9]+?):/g, '"$1":');
    } else {
        return $2; 
    } 
});

var data = JSON.parse(newJson);
alert(data[0]["Name"]);

This will match any variables (alphanumeric) that end with a colon :, but will ingore any matches that are found between quotes (i.e. data string values)

Here is an example

Gerhart answered 25/4, 2013 at 11:54 Comment(8)
So no colons would be allowed inside data strings?Cyanamide
@GSerg: No, of course not, don't be silly! but yeah, it is definitely flaky, but if these assumptions can be made about the JSON data then it will be fine.Gerhart
@Gerhart thanks for your prompt and thorough reply! Some field names have underscores. e.g. Default__c (Salesforce Custom Fields!) but the regex does not like them. I need to allow for the "_c" or "" in field names. Thoughts?Pentothal
@nelsonic: If you want underscores then you can use this regex for the replace part: $1.replace(/([_a-zA-Z0-9]+?):/g, '"$1":');Gerhart
Works until I get a url e.g. example.com becomes "http:"//example.com which breaks the JSON. and a Date-Time Stamp with colon separators: 2013-04-25T08:41:42.000+0000 becomes "2013-04-"25T08":"41":42.000+0000" which also breaks JSON.parsePentothal
@nelsonic: Then your data is too complicated to parse this way. It's not real JSON to begin with so if you are doing more complicating than the string data in your original examples, then I would suggest you make the input valid, or try MaximilianoBecerraBus's solutionGerhart
@Gerhart agreed. the data is too complicated. I tried to phrase the question in a simple way. but given the URLs and data containing single quotes and colons etc. I am forced to be more creative. Thank you very much for your answer I will vote it up!Pentothal
please explain this part json.replace(/([a-zA-Z0-9]+?):/g, '"$1":'); i'm not understand @GerhartUnderstrapper
J
2

Create a javascript class, populate the object with your input and then convert it in a clean json using: JSON.stringify(object) to avoid errors . My full post here .

NOTE: if you use IE7 or less version you must add the JSON.js library to use JSON.stringify() function.

Jennajenne answered 25/4, 2013 at 12:2 Comment(5)
i forget specify the version :PJennajenne
This is the way to go. In the client stringify the object with JSON.stringify(). The server will receive a valid json.Savagism
@MaximilianoBecerraBustamante My question has nothing to do with I.E or converting strings on the Client Side. I tried to make it clear in the question that I have no control over the input. I am receiving the data as a string so JSON.stringify(string) is useless to me... :-(Pentothal
@Pentothal Did you see my blog entry? JSON.stringify is the last step of the solution, the key of the proposed solution is create a javascript class ( could it be a complex object with many levels ) and then create a instance of that class and fill it with the data generated in the input (your data string). When you have your object ready and filled you may use JSON.stringify to generate your clean JSON based in a javascrit object (Constructed using a javascript class) :-)Jennajenne
@Pentothal if you don't need JSON.stringify function, objects in javascript es the best way to store your data with a defined structure and then you can process it as you like :-)Jennajenne

© 2022 - 2024 — McMap. All rights reserved.