How to navigate in nested JSON - javascript

I have nested JSON object like
{"baseball":
{"mlb":
{"regular":
{"_events": [{"start_time": "2011-07-31 17:35", "lines":
[{"comment": "", "coeff": "2.35", "title": "2", "old_coeff": "2.35", "is_main": true},
{"comment": "", "coeff": "1.59", "title": "2", "old_coeff": "1.59", "is_main": true},
{"comment": "", "coeff": "1.59", "title": "2", "old_coeff": "1.59", "is_main": true},
{"comment": "", "coeff": "2.35", "title": "2", "old_coeff": "2.35", "is_main": true}],
"members": ["atlanta", "florida"]
}
]
}}}}
And i need get _events array and parse it too. But I don't know what will be in cells before _events and how they will. How do I work with this structure?

function recursiveGetProperty(obj, lookup, callback) {
for (property in obj) {
if (property == lookup) {
callback(obj[property]);
} else if (obj[property] instanceof Object) {
recursiveGetProperty(obj[property], lookup, callback);
}
}
}
And just use it like this:
recursiveGetProperty(yourObject, '_events', function(obj) {
// do something with it.
});
Here's a working jsFiddle: http://jsfiddle.net/ErHng/ (note: it outputs to the console, so you need to Ctrl+Shift+J/Cmnd+Option+I in chrome or open firebug in Firefox and then re-run it)

If the structure is known:
Assuming that you have the above in a String called input (and that the JSON is valid):
var obj = JSON.parse(input) // converts it to a JS native object.
// you can descend into the new object this way:
var obj.baseball.mlb.regular._events
As a warning, earlier versions of IE do not have JSON.parse, so you will need to use a framework for that.
If the structure is unknown:
// find the _events key
var tmp = input.substr(input.indexOf("_events"))
// grab the maximum array contents.
tmp = tmp.substring( tmp.indexOf( "[" ), tmp.indexOf( "]" ) + 1 );
// now we have to search the array
var len = tmp.length;
var count = 0;
for( var i = 0; i < len; i++ )
{
var chr = tmp.charAt(i)
// every time an array opens, increment
if( chr == '[' ) count++;
// every time one closes decrement
else if( chr == ']' ) count--;
// if all arrays are closed, you have a complete set
if( count == 0 ) break;
}
var events = JSON.parse( tmp.substr( 0, i + 1 ) );

The easiest thing to do in this situation, I find, is to go to JSFiddle, paste in your json as a variable:
var json = {"baseball": ... etc.
console.log(json);
Then using Chrome, "View" -> "Developer" -> "Javascript console" start to experiment with what the data structure looks like in order to build up your parsing function.
Then start experimenting with the structure. Eg.
console.log(json.baseball.mlb.regular._events);
Or if you turn on JQuery:
$.each(json.baseball.mlb.regular._events, function(i, item){
$.each(item.lines,function(i,line){
console.log(line.coeff);
});
});
If you're having trouble actually loading in this JSON into a variable you'll need to JSON.parse a string retrieved via an AJAX call I suspect.

Related

Object doesn't support property or method IE11 (Compatibility Mode) - knockoutjs

Essentially what I am trying to achieve here is to check if the Barcode inputted/scanned on the form which is stored in self.trackfile is already in the list of files.
self.files() is an array of arrays, each time the file is added it pushes another array from self.trackfile into self.files(), once all the files have been added into the list they can be 'tracked' and sent back to the server.
I am having trouble getting this to work in IE11 (Compatibility Mode), this works fine in Chrome. I have done some searching around and not found a workaround.
The line var fb = self.files()[x].Barcode(); throws the following error in IE: Object doesn't support property or method 'Barcode'.
If you could help me identify a workaround that would be fantastic!
addFile Script
self.addFile = function () {
var index = 0;
if(index < self.files().length){
var i = 0;
for (x in self.files()){
var fb = self.files()[x].Barcode();
var tb = self.trackfile.Barcode();
if(fb==tb){
i += 1;
}
}
if(i > 0){
alert("Error: File Already Exists in List");
}
else {
self.files.push(new TrackFile(self.trackfile));
}
}
else {
self.files.push(new TrackFile(self.trackfile));
}
}
Example of files()
[
{
"Location": "Location 1",
"TransactionMode": "Send",
"ServicePoint": "Service Point 2",
"Status": "Incomplete / Open",
"Comments": "",
"Barcode": "0123456789",
"BarcodeImageBase64": ""
},
{
"Location": "Location 1",
"TransactionMode": "Send",
"ServicePoint": "ServicePoint 1",
"Status": "Incomplete / Open",
"Comments": "",
"Barcode": "9876543210",
"BarcodeImageBase64": ""
}
]
console.log(self.files()[x]);
Try looping through your array with indexes instead of the for (x in foo) construct. You're probably running into a random property on the prototype of the array that IE adds which obviously wouldn't contain a Barcode.
See: Why is using "for...in" with array iteration a bad idea?
So I figured out how to get around this rather than trying to return a value from a nested array I created an array of just the barcodes:
self.justBarcodes = ko.computed(function() {
var barcodes = ko.utils.arrayMap(this.files(), function(item) {
return item.Barcode();
});
return barcodes.sort();
}, self);
Then I looped through the self.justBarcodes() array to check if the barcode already exists:
for (var x = 0; x < self.justBarcodes().length; x++){
var fb = self.justBarcodes()[x];
var tb = self.trackfile.Barcode();
if(fb==tb){
i += 1;
}
}
Now it works as it should!

Access JSON key value dynamically using jquery

Below is my json which is dynamic. I want to access 'bf' key in the json , 'xxxxxx20160929' and 'yyy813AI20160929' keys are dynamic but json structure will be the same
{
"resultData": [
{
"a": "124",
"b": "0",
"c": "0",
"flc_schedu": {
"e": "6",
"f": "en",
"xxxxxx20160929": [
{"ID": "yyyyyyyy" },
{"ID": "fffff"}
]
},
"fareDetails": {
"xxxxxx20160929": {
"yyy813AI20160929": {
"O": {
"AD": {
"bf": "2527"
}
}
}
}
}
}
]
}
Below is how I tried
response.resultData[0].fareDetails[Object.keys(response.resultData[0].fareDetails)[0]]
If I try as above I can able to access dynamically up to "xxxxxx20160929" key, but I can't able get how to reach up to "bf" key dynamicaly.
You can reference an object using the array syntax.
var one = 'xxxxxx20160929';
var two = 'yyy813AI20160929';
data.resultData[0].fareDetails[one][two].O.AD.bf;
UPDATE:
This code assumes there is only one dynamic object at each layer.
var one = Object.keys(data.resultData[0].fareDetails)[0];
var two = Object.keys(data.resultData[0].fareDetails[one])[0];
var thing = data.resultData[0].fareDetails[one][two].O.AD.bf;
function getBFFromFareDetails(details){
var bfValues = [];
for(var k in details.fareDetails){
// loop over the children of fareDetails
if( details.fareDetails.hasOwnProperty( k ) ) {
//each entry in ;fareDetails'
var itemRoot = details.fareDetails[k]
for(var k1 in itemRoot){
// loop over the children of the first unknown item
if( itemRoot.hasOwnProperty( k1 ) ) {
//return the bf from the first unknown child
return itemRoot[k1].O.AD.bf;
}
}
}
}
}
If you call this with var bf = getBFFromFareDetails(response.resultData[0])
this will return the value for the first bf in the first child of fareDetails and its first child.
You can see a quick example in action here https://jsfiddle.net/tocsoft/5364x2sp/
If you are able to access up to "xxxxxx20160929" level then create a var to store that level, then use that variable to access the next which you will need to store in a variable, then use both variable to access the key needed.
var1 = response.resultData[0].fareDetails)[0];
var2 = response.resultData[0].fareDetails)[0][var1];
response.resultData[0].fareDetails)[0][var1][var2];

Read JSON data from javascript and trim string

I have json file like this,
{
"data":{
"type": "runjob",
"id": "1",
"inputs": [
{
"name": "input",
"value": "d:\\My\\filestore\\JMJ\\Content\\input.xml"
},
{
"name": "cmd",
"value": "test.js //NoLogo"
},
{
"name": "output",
"value": "d:\\My\\filestore\\JMJ\\Content\\output.xml"
}
],
"disabled": false
}
}
I need to read the velues, input.xml and output.xml using javascript.. How can I get those value?
var stdin = WScript.StdIn.ReadAll();
var json = eval('(' + stdin + ')');
var log = new Log(json.data.inputs[?]);
json.data.inputs is an array (note it's json; as Tushar pointed out, you have had jason in the question). So you can use any technique for accessing or looping through an array that's supported by your environment. It look slike you're using JScript on Windows Script Host; last I checked it didn't even have ES5 features, so perhaps a simple for loop:
var i;
var inputs = json.data.inputs;
for (i = 0; i < inputs.length; ++i ){
// Here, inputs[i].name will be the name ("input", "cmd", "output")
// and inputs[i].value will be the value ("d:\\My\\filestore\\JMJ\\Content\\input.xml", for instance)
}
json.data.inputs is an array containing 3 json objects; you want the value property of the first and the third elements:
json.data.inputs[0].value; // "d:\\My\\filestore\\JMJ\\Content\\input.xml"
json.data.inputs[2].value; // "d:\\My\\filestore\\JMJ\\Content\\output.xml"

Convert JSON to HTML: Uncaught TypeError: json.forEach is not a function

I want to convert JSON to HTML to display it on website. I've googled, and this error occurs when when json is a string, and first I need to parse. But when I use JSON.parse, the console says it is already an object (Unexpected token o in JSON at position 1).
$(document).ready(function() {
$("#getMessage").on("click", function() {  
$.getJSON("http://quotes.rest/qod.json", function(json) {
var html = "";
json.forEach(function(val) {
var keys = Object.keys(val);
html += "<div class = 'blabla'>";
keys.forEach(function(key) {
html += "<b>" + key + "</b>: " + val[key] + "<br>";
});
html += "</div><br>";
});
$(".message").html(html);
});
});
});
json is an object, not an array. You can use forEach only on arrays.
As you have done already, you can iterate over the object's keys like this:
Object.keys(json).forEach(function(key) {
var value = json[key];
...
});
In addition to what everyone else said, it appears that the JSON response does not look like you think it does.
var json = {
"success": {
"total": 1
},
"contents": {
"quotes": [{
"quote": "It's not whether you get knocked down, it...s whether you get up.",
"length": "65",
"author": "Vince Lombardi",
"tags": [
"failure",
"inspire",
"learning-from-failure"
],
"category": "inspire",
"date": "2016-08-09",
"title": "Inspiring Quote of the day",
"background": "https://theysaidso.com/img/bgs/man_on_the_mountain.jpg",
"id": "06Qdox8w6U3U1CGlLqRwFAeF"
}]
}
};
var messageEl = document.querySelector('.message');
messageEl.innerText = json.contents.quotes[0].quote;
<div class="message"></div>
$.getJson already transforms a JSON object into a javascript object, so you would not need to parse it again.
However, your problem starts with forEach, which is an Array method, not an Object method, therefor it will not work in your use case.
var jsonKeys = Object.keys(json); jsonKeys.forEach(...) will work, as Object.keys returns an array of Object keys.

How to parse dynamic json data?

I am using wikipedia API my json response looks like,
"{
"query": {
"normalized": [
{
"from": "bitcoin",
"to": "Bitcoin"
}
],
"pages": {
"28249265": {
"pageid": 28249265,
"ns": 0,
"title": "Bitcoin",
"extract": "<p><b>Bitcoin</b>isapeer-to-peerpaymentsystemintroducedasopensourcesoftwarein2009.Thedigitalcurrencycreatedandlikeacentralbank,
andthishasledtheUSTreasurytocallbitcoinadecentralizedcurrency....</p>"
}
}
}
}"
this response is coming inside XMLHTTPObject ( request.responseText )
I am using eval to convert above string into json object as below,
var jsonObject = eval('(' +req.responseText+ ')');
In the response, pages element will have dynamic number for the key-value pair as shown in above example ( "28249265" )
How can I get extract element from above json object if my pageId is different for different results.
Please note, parsing is not actual problem here,
If Parse it , I can acess extract as,
var data = jsonObject.query.pages.28249265.extract;
In above line 28249265 is dynamic, This will be something different for different query
assuming that u want to traverse all keys in "jsonObject.query.pages".
u can extract it like this:
var pages = jsonObject.query.pages;
for (k in pages) { // here k represents the page no i.e. 28249265
var data = pages[k].extract;
// what u wana do with data here
}
or u may first extract all page data in array.
var datas = [];
var pages = jsonObject.query.pages;
for (k in pages) {
datas.push(pages[k].extract);
}
// what u wana do with data array here
you can archive that using two methods
obj = JSON.parse(json)
OR
obj = $.parseJSON(json);
UPDATE
Try this this
var obj = JSON.parse("your json data string");
//console.log(obj)
jQuery.each(obj.query.pages,function(a,val){
// here you can get data dynamically
var data = val.extract;
alert(val.extract);
});
JSBIN Example
JSBIN

Categories

Resources