Kenny Peng Kenny Peng - 5 months ago 116
Javascript Question

Sending/Parsing multiple JSON objects

I have a Sinatra server that is returning multiple JSON objects from the database in a streaming manner. The objects would look like:

{"a": 1, "b": 2, "c": 3}
{"a": 4, "b": 5, "c": 6}
...


but this is invalid JSON. I can add a hack into Sinatra's event processing (manually injecting the missing array delimiters) to make the response look like:

[
{"a": 1, "b": 2, "c": 3}
, {"a": 4, "b": 5, "c": 6}
]


which is valid JSON now, but this technique is inelegant. Is there some way to do this client-side? Basically, what I want is to have a JavaScript function read a string and consume a valid JSON object, and then return to me the JSON object and the remainder of the string, iteratively being called until the entire string is consumed.

Answer

The native JSON.parse() function expect the whole string to be valid JSON. I'm not aware of a parser that only consumes the first valid object as you'd like. And people should really be producing valid JSON anyways.

If you know that there is one object per line you could simply split the string by line using the split() function and parse each line individually.

var str = '{"a": 1, "b": 2, "c": 3}\n'+
          '{"a": 4, "b": 5, "c": 6}';

var strLines = str.split("\n");


for (var i in strLines) {
  var obj = JSON.parse(strLines[i]);
  console.log(obj.a);
}

You could also use a bit of string manipulation to transform each line into an array element and parse the whole thing.

str = "["+str.replace(/\n/g, ",")+"]";
JSON.parse(str);