My JSON is like below
{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}}
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
{"_id":1283378,"name":"Gorkhā","country":"NP","coord":{"lon":84.633331,"lat":28}}
{"_id":1270260,"name":"State of Haryāna","country":"IN","coord":{"lon":76,"lat":29}}
{"_id":708546,"name":"Holubynka","country":"UA","coord":{"lon":33.900002,"lat":44.599998}}
It is a JSON without comma separation, how to read this file? I tried to parse the JSON and add commas in between, but couldn't do that either.
myapp.controller('Ctrl', ['$scope', '$http', function($scope, $http) {
$http.get('todos.json').success(function(data) {
var nuarr = data.toString().split("\n");
for(i in nuarr) {
myjson.push(i+",");
}
});
}]);
My JSON is like below
{"_id":707860,"name":"Hurzuf","country":"UA","coord":{"lon":34.283333,"lat":44.549999}}
{"_id":519188,"name":"Novinki","country":"RU","coord":{"lon":37.666668,"lat":55.683334}}
{"_id":1283378,"name":"Gorkhā","country":"NP","coord":{"lon":84.633331,"lat":28}}
{"_id":1270260,"name":"State of Haryāna","country":"IN","coord":{"lon":76,"lat":29}}
{"_id":708546,"name":"Holubynka","country":"UA","coord":{"lon":33.900002,"lat":44.599998}}
It is a JSON without comma separation, how to read this file? I tried to parse the JSON and add commas in between, but couldn't do that either.
myapp.controller('Ctrl', ['$scope', '$http', function($scope, $http) {
$http.get('todos.json').success(function(data) {
var nuarr = data.toString().split("\n");
for(i in nuarr) {
myjson.push(i+",");
}
});
}]);
Share
Improve this question
edited Mar 21, 2016 at 3:46
user663031
asked Mar 21, 2016 at 2:50
alexalex
1131 gold badge4 silver badges6 bronze badges
3
|
9 Answers
Reset to default 7This format is typically called "newline-delimited JSON" or "ndjson"; there are several modules that can parse this, but if you're data set is small and you can do it all at once, you're on the right track:
var ndjson = "..." // assuming your data is already loaded in as a string
var records = ndjson.split('\n').map(function (record) {
return JSON.parse(record)
})
That simplifies it a bit, but then you have all of your records in an array, as parsed JSON objects. What you do to them after that is up to you, but the key takeaway here is that your JSON is a list of objects, not a single object: you don't want to parse it as a whole, but as individual records.
Say then, you want to create an object whose keys are the individual IDs; that might be helpful:
var recordHash = {}
records.forEach(function (record) {
recordHash[record._id] = record
})
Now you can address the individual records as recordHash['12345678']
assuming that 12345678
is the id of the record you wanted. You'll want to mutate the records into whatever data structure makes sense for your application, so it really depends on what you're looking for, but that example might get you started.
I really don't recommend trying to mutate the data that you're receiving into some other format before parsing; it's fragile. You'll find it much safer and more re-usable to parse out the data in the way you were provided it, and then transform it into whatever data structure makes sense for your application.
$http.get
expects that response must be json. You can write your own custom response transformer to do that so.
$http({
url: 'todos.json',
method: 'GET',
transformResponse: function (data) {
return data.split('\n').map(function(line) {
return JSON.parse(line);
});
}
}).success(function (response) {
console.log(response);
// do whatever you want to do
// response will be of type array of objects
});
Your JSON needs to be a single object or array. Just joining a bunch of objects together with a comma does not define a single JSON object. Try this instead to get a parsable array of objects:
var nuarr = data.toString().split("\n");
myjson = '[' + nuarr.join(',') + ']';
Then JSON.parse(myjson)
should return an array of objects. Alternatively, you can just map each element of nuarr
to it's JSON-parsed value and collect the results in another array.
var myJson = nuarr.join(',');
But what are you really trying to do? Your code is pushing the strings with a comma added into an array, so end up with
["{...},", "{...},", ...]
As I see it, You have a collection of json objects, with the delimiter as newline.
Try this:
myapp.controller('Ctrl', ['$scope', '$http', function($scope, $http) {
$http.get('todos.json').success(function(data) {
myjson = data.split("\n").map(function(line) { return JSON.parse(line); });
});
}]);
Use a regexp to split into lines, then map each line into its JSON-parsed equivalent, yielding an array of the objects on each line:
input . match(/^.*$/gm) . map(JSON.parse)
Or use split
as other answers suggest:
input . split('\n') . map(JSON.parse)
$http.get expects that response must be json. You can write your own custom response transformer to do that so.
$http({
url: 'todos.json',
method: 'GET',
transformResponse: function (data) {
return data.split('\n').map(function(line) {
return JSON.parse(line);
});
}
}).success(function (response) {
console.log(response);
// do whatever you want to do
// response will be of type array of objects
});
As stupid as it may seem, we got tired of using commas and quotes with JSON, along with not having comments or multiline strings.
Knowing that Douglas Crockford and his disciples would cry 'Blasphemy', we proceeded to write a specification, parser, and formatter for our own Relaxed Json syntax.
The fact is you don't really need commas, and quotes are only needed in a few exceptional cases. And you don't need newlines either.
With Relaxed Json, to make your example work, you would just put '[' and ']' around what you already have and call
val realJson = parser.stringToJson(...)
But you don't need newlines between the array values.
And you can also remove all the commas in-between your key-values.
And you don't need quotes around your keys.
So you could do this:
[
{ _id:707860 name:Hurzuf country:UA
coord:{lon:34.283333 lat:44.549999}
}
{ _id:519188 name:Novinki country:RU
coord:{lon:37.666668 lat:55.683334}
}
]
Link To Specification: http://www.relaxedjson.org
Link To NPM https://www.npmjs.com/package/really-relaxed-json
Paste the example here to see how easy it is to parse: http://www.relaxedjson.org/docs/converter.html
Update 2022
@milkandtang answer put me on the right path but JSON.parse()
gave me trouble and returned errors even after splitting the lines. It keeps complaining about lines being empty or malformated.
This is what works for me with New-Line Delimited JSON
var ndjson = data;//must be a string
//declare variable that will be array of json
var json = [];
//split
ndjson.split('\n').map(function (record) {
//regex to format each array to a json object
var array = JSON.parse(`[${record.replace(/\}\n\{/g, '},{')}]`);
//push to json array
json.push(array);
})
//pheeew...
console.log(json);
jq --slurp
will convert this to a JSON array. – Brent Bradburn Commented May 10, 2023 at 22:45