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+",");
}
});
}]);
This 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.
$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
});
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)
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);
Related
I have a JSON string something similar to:
string str=[
{"name": "Dukes",
"lastname":"Chavez",
"salary":"10000",
"clearingbankAccinfo":"Westpac"}]
The issue is we have to clear the bank info, and that can be any value.
What we know for sure is it would come at the end of the string.
I need a regex pattern to remove this clearingbankAccInfo so that it looks something similar to:
string str=[
{"name": "Dukes",
"lastname":"Chavez",
"salary":"10000"}]
Unfortunately I would have not accepted this as input itself but this information comes from a diff process and I have no control over what they pass.
I have tried:
String str=str.replace(',"clearingbankAccInfo":\g[a-zA-Z0-9_:]\g+', '' )
But it doesn't work correctly
If you're working with something like JSON regex is the wrong solution. Simply parse the stringified data, and loop over it with something like map to extract and return the correct data. Then you can just make a string again out of that data.
const str = '[{"name": "Dukes","lastname": "Chavez","salary": "10000","clearingbankAccinfo": "Westpac"},{"name": "Bob","lastname": "Smith","salary": "20000","clearingbankAccinfo":"Lloyds"}]';
// Here we're creating a new variable called `newData` to hold
// the transformed data. We parse the data string and iterate over it
// (because it's now an array) with `map` which is an array method.
// With each iteration we take the object, grab the clearingBankAccinfo
// and just return everything else.
const newData = JSON.parse(str).map(obj => {
const { clearingbankAccinfo, ...rest } = obj;
return rest;
});
console.log(newData);
console.log(JSON.stringify(newData));
Additional documentation
Rest parameters
Working with JSON
Destructuring assignment
str=str.replace(/,?"clearingbankAccinfo":"\w+"/g, '');
I am currently making an ajax call to return data from an API. The return value is an object of an array. This format is an invalid object so I am having issues accessing the data that is being returned to me.
How can I convert this object into a valid json object so I can access the data that is being returned?
Here is an example of the data being returned:
data = { ["<p>Retail Websites has a profit value of $243,291. In the year 2020 we have seen a growth rate of about 2.3% </p>" ] }
I've tried using dataType: json in my ajax call but the result value is still the same.
Here is my ajax call using "dataType: json" :
$.ajax({
type: "POST",
url: dataUrl,
data: {
"retailId": retailId,
},
dataType: "json",
async: true,
error: function () {
console.log("error")
}
}).done(function (data) {
console.log("retail data", data)
})
I am unable to access the data in this object. I am expecting to be able to access the data like a json object such as : data[0]. I am stuck on how to accomplish this.
If your data is set as:
var data = { ["<p>Retail Websites has a profit value of $243,291. In the year 2020 we have seen a growth rate of about 2.3% </p>" ] }
Then the problem is the curly braces with no key. When you remove them, the array is correct. data[0] is equal to the string you expect.
If the result of your API call is the whole of data = {...} and you know that it is, then you can capture the string, remove the characters at the beginning and end that don't belong (everything outside the square brackets) and use JSON.parse to get your JSON data. There are several ways to remove the characters. If the text is always the case, you can use substrings, or if you need to be more flexible, you can use regular expressions.
I'm currently trying to parse the following JSON output.
These JSON objects are stored in one big string and not in a JSON array. As such it is not valid JSON.
{"output": "te\ns\nt"}
{"output": "test"}
This string also contains multiple new lines. So splitting on new lines is not an option.
Nevertheless is there any way of parsing this invalid JSON that it results in a valid array of JSON objects?
If your object-list (let's call it that) contains valid objects you can first make an array from each line and then go through that array and parse the JSON:
let data = `{"output": "test"}
{"output": "test"}`; //template string to make the newlines work flawless...
// first split on newline filter out "" map to the parsed JSON
data = data.replace(/}\n*/g, "}**").split("**") .filter(Boolean) .map(JSON.parse);
console.log(data);
Here's something dirty that might work.
let string = `{"output": "te\ns\nt"}
{"output": "test"}`
let json = JSON.parse(`[${string.replace(/}[\s]*\{/g, '}, {').replace(/\n/g, '\\n')}]`)
console.log(json) // [ { output: 'te\ns\nt' }, { output: 'test' } ]
Not pretty and quite fragile, but quick.
is there anyway i can get this malformed json format which is odd i have no control over this json manually so i need to get this data and manipulate it with rxjs observable from http get
{
"firstNm": "Ronald",
"lastNm": "Mandez",
"avatarImage": "https://randomuser.me/api/portraits/men/74.jpg"
}
{
"firstNm": "Ronald",
"lastNm": "Mandez",
"avatarImage": "https://randomuser.me/api/portraits/men/74.jpg"
{
"firstNm": "Ronald",
"lastNm": "Mandez",
"avatarImage": "https://randomuser.me/api/portraits/men/74.jpg"
}
I tried with your JSON in the console and this seems to work. In the map function I've used you can probably implement more generic replacement methods to alter the strings, but it works for this example.
function fixBadJSON(response){
let badJSON = JSON.stringify(response); // added this edit in case you don't know how to get the response to a string
let arr = badJSON.split('}\n'); // Looks like the JSON elements are split by linefeeds preceded by closing bracket, make into arr length of 3
let fixedArr = arr.map((item)=>{ // map the array to another, replace the comma at the end of the avatarImage key. elements in array should be proper JSON
if(item[item.length] != '}') item += '}'; //put the brackets back at thend of the string if they got taken out in the split, probably a better way to handle this logic with regex etc
return item.replace('jpg",','jpg"')
});
let parsedJSON = JSON.parse(JSON.stringify(fixedArr));
return parsedJSON
}
Take the JSON data you've posted up there and copy it to a variable as a string and test the function, it will return a properly formatted array of JSON data.
Call that when you get a response from your service to transform the data. As far as the observable chains and any async issues you might be seeing those are separate things. This function is just designed to convert your malformed JSON.
My Existing Code and Explanation
Working Fine, But I want to Create a template like Its should read JSON Data that Having keys in any name, I am Always reading data from JSON object in 2nd Position
Now I read the JSON that passed in the argument (data) inside that using the for loop extract single object in group, after that get the data using key(Module_Name).. I know the key(Module_Name) is always present in second position only, Now its Working Fine with keyname rather i want to fetch the data using position, that also used as template in my other modules
/* render Screen Objects */
screenRenderer.displayScreens = function(data)
{
screenRenderer.renderLayout(function(cont, boo)
{
if (boo)
{
for(i=0;i<data.length;i++)
{
var buttons = "<button class='screen_button'>"+data[i].Module_Name+"</button>";
$("#screen-cont").append(buttons);
}
}
else
{
scr_cont.show();
}
})
}
This is My Requirement, kindly awaiting suggestions, answers..
Thanks in Advance
You can use the function Object.keys(obj) to get all keys of an object as array, which you can access with an Index and than use the String you get to access the property.
So it could look like this:
var obj = data[i];
var keys = Object.keys(obj);
var result = obj[keys[1]];
Hope this is what you want.