Iterate over json object having an object - javascript

I have the following json output from an ajax call ,
{17: {access: "1",id: "2"}}
I'd like to iterate and get value of id , I am using below code but I get error of undefined in console .
$(obj).each(function(i, val) {
console.log(val.id);
});
What am I doing wrong ?

You can do it like this:
var obj = {17: {access: "1",id: "2"}}
// Native JS
for (var k in obj) {
console.log(obj[k].id)
}
// JQuery
// Documentaion: http://api.jquery.com/jquery.each/
$.each(obj, function(i, val) {
console.log(val.id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Hope it helps, any questions?
As requested I'd like to point out that the term "JSON-Object" doesn't realy exist. You are using a simple JavaScript-Object, wich can be made of an JSON-String 😇

In this case you should use $.each from jQuery utils
var obj = {17: {access: "1",id: "2"}}
$.each(obj, function(i, val) {
console.log(val.id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

You have to use $.each(array, callback):
var obj = {
17: { id: "2", access: "1" },
23: { id: "8" }
};
$.each(obj, function(i, val) {
console.log(val.id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

Try the below code.
var obj = {17: {access: "1",id: "2"}};
if( $.isPlainObject(obj) ) {
$(obj).each(function(i, val) {
console.log(val.id);
});
}
else {
console.log('invalid Object');
}

A solution with Object.keys() and Array.prototype.some() in a recursion style.
var object = { 17: { access: "1", id: "2" } };
function find(p, o) {
var result;
Object.keys(o).some(function (k) {
if (k === p) {
result = o[k];
return true;
}
if (typeof o[k] === 'object') {
result = find(p, o[k]);
}
});
return result;
}
document.write('<pre>' + JSON.stringify(find('id', object), 0, 4) + '</pre>');

You are making an jQuery object of your JSON and then iterating over that jQuery object. Take a look at the API docs of jQuery.each():
You are supposed to use it like this:
jQuery.each(object, callback)
Where object is the object to iterate over and callback is the callback function to be run for every key in object.
var obj = {
17: {
access: "1",
id: "2"
},
18: {
access: "2",
id: "5"
}
};
$.each(obj, function(i, val) {
document.body.innerHTML += val.id + "<br>";
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

Can an objects property, which is a function, be recursively called within itself?

I keep getting an error "Uncaught TypeError: this.setTestType is not a function" when trying to recursively call my setTestType function in my object.
Is recursion not allowed when defining a function as an object property and trying to call itself?
var resultGaAuto = [{
bestPracticeID: "344033"
}];
var resultAuto = [{
bestPracticeID: "111111"
}];
var AST = {
handleSave: function() {
var data = {};
var gaRecords = this.processResults(resultGaAuto);
var autoRecords = this.processResults(resultAuto);
//console.log(gaRecords);
//console.log(autoRecords)
var testTypeGaRecords = this.setTestType(gaRecords, 5);
var testTypeAutoRecords = this.setTestType(autoRecords, 4);
console.log(testTypeGaRecords);
data.records = Object.assign({}, testTypeGaRecords,
testTypeAutoRecords);
console.log(data);
},
setTestType: function(obj, num) {
Object.keys(obj).forEach(function(key) {
if (key === "testResult") {
return (obj[key] = num);
}
//*******ERROR*******
return this.setTestType(obj[key], num);
});
},
processResults: function(results) {
var records = {};
$.each(results, function(i, result) {
records[result.bestPracticeID] = records[result.bestPracticeID] || {
violation: {
violationID: result.bestPracticeID
},
instances: []
};
records[result.bestPracticeID].instances.push({
lineNumber: 1,
element: "testEl",
attribute: "testAttr",
xpath: "testPath",
testResult: 3
});
});
return records;
}
};
AST.handleSave();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
The bound context of your anonymous function should be AST
setTestType: function(obj, num) {
Object.keys(obj).forEach(function(key) {
if (key === "testResult") {
return (obj[key] = num);
}
//*******ERROR*******
return this.setTestType(obj[key], num);
}.bind(AST)); // see the bound context!
}
Can an objects property, which is a function, be recursively called within itself?
Yes. There is no technical limitation here. Just incorrect code.
Uncaught TypeError: this.setTestType is not a function
this is wrong.
Fix
setTestType: function(obj, num) {
Object.keys(obj).forEach(function(key) {
if (key === "testResult") {
return (obj[key] = num);
}
//*******FIXED*******
return AST.setTestType(obj[key], num);
});
},
More
Read up on this : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this

show nested json data in treeview in javascript

i have nested json data. i used the blow function.
var jsonSource={"error_code":0, "ext_info":{"name":{"firstName":"John","lastName":"Jonson","nickName":"JJ"}}};
var obj=JSON.parse(jsonSource),returnValue;
function showJson(obj){
for(var key in obj){
if(typeof obj[key]==='object'){
returnValue+='<div>'+key+'/\n';
showJson(obj[key]);
returnValue+='</div>';
} else{
returnValue+=key+'equal'+obj[key];
}
}
docoument.getElementById('data').innerHTML=returnValue;
}
as i said before , i have a large nested json data and when i parse it to showJson function ,it just shows one level of json data and puts others deep level of dataJson undefined.
what should i do to resolve the problem?
Recursive approach works more intuitively when done with actual return values. Have a look at https://jsfiddle.net/ughnjfh0/1/
var jsonSource='{"error_code":0, "ext_info":{"name":{"firstName":"John","lastName":"Jonson","nickName":"JJ"}}}';
var obj=JSON.parse(jsonSource);
function showJson(obj){
var returnValue='';
for(var key in obj){
if(typeof obj[key]==='object'){
returnValue+='<div>'+key+'/\n';
returnValue+=showJson(obj[key]);
returnValue+='</div>';
} else{
returnValue+=key+'equal'+obj[key];
}
}
return returnValue;
}
document.getElementById('data').innerHTML= showJson(obj);
Also:
jsonSource should be a string to be properly parsable as JSON data
typo in docoument.getElementById('data').innerHTML=returnValue;
Some of your problems:
jsonSource is already an object
you try to assign the returnValue in every call of showJson
Better to use a clean approach for looping and returning of the items:
var obj = { "error_code": 0, "ext_info": { "name": { "firstName": "John", "lastName": "Jonson", "nickName": "JJ" } } };
function showObj(obj) {
return Object.keys(obj).map(function (k) {
if (typeof obj[k] === 'object') {
return k + ':<br><div style="margin-left: 25px;">' + showObj(obj[k]) + '</div>';
}
return k + ': ' + obj[k];
}).join('<br>');
}
document.getElementById('data').innerHTML = showObj(obj);
<div id="data"></div>
// obj is the object to loop, ul is the ul to append lis to
function loop(obj, ul) {
$.each(obj, function(key, val) {
if(val && typeof val === "object") { // object, call recursively
var ul2 = $("<ul>").appendTo(
$("<li>").appendTo(ul)
);
loop(val, ul2);
} else {
$("<li>").text(val).appendTo(ul);
}
});
}
var ul = $("<ul>");
var jsonSource={"error_code":0, "ext_info":{"name":{"firstName":"John","lastName":"Jonson","nickName":"JJ"}}};
var data=JSON.parse(jsonSource)
loop(data, ul);
ul.addClass("my-new-list").appendTo('body');

get specific text from value with javascript

I have a json.json file like this
{
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
}
And this script im using to read the file
<script type='text/javascript'>
$(window).load(function(){
$.getJSON("json.json", function(person){
document.write(person.name3);
});
});
</script>
This script is made to point out all of the data from "name3" but i need only "dr3" value from "name3" to be stored to be written.
How to do that?
You can store it like this using combination of split() calls.
var dr3val = person.name3.split("&")[2].split("=")[1];
console.log(dr3val); // "Sting3"
The above will work if the order is same. Else you can use the below
var dr3val = person.name3.replace(/.*?dr3=(.+)?&.*/,"$1");
console.log(dr3val); // "Sting3"
You should change your json to this:
{
"name1":
{
"ts1" : "Hallo",
"ts2" : "Hillarry",
"ts3" : "Sting",
"ts4" : "Storm"
}
}
this way it makes your jsonstring much easier to use.
Get the data from it like this:
person.name1.ts1
var json = {
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
};
var name3 = json.name3.split('&');
for (var i = 0; i < name3.length; i++) {
if (name3[i].indexOf("dr3=") > -1) {
var value = name3[i].replace("dr3=", "");
alert(value);
}
}
Implement this jQuery plugin i made for a similar case i had to solve some time ago. This plugin has the benefit that it handles multiple occurring variables and gathers them within an array, simulating a webserver behaviour.
<script type='text/javascript'>
(function($) {
$.StringParams = function(string) {
if (string == "") return {};
var result = {},
matches = string.split('&');
for(var i = 0, pair, key, value; i < matches.length; i++) {
pair = matches[i].split('=');
key = pair[0];
if(pair.length == 2) {
value = decodeURIComponent(pair[1].replace(/\+/g, " "));
} else {
value = null;
}
switch($.type(result[key])) {
case 'undefined':
result[key] = value;
break;
case 'array':
result[key].push(value);
break;
default:
result[key] = [result[key], value];
}
}
return result;
}
})(jQuery);
</script>
Then in your code do:
<script type='text/javascript'>
$(window).load(function(){
var attributes3;
$.getJSON("json.json", function(person){
attributes3 = $.StringParams(person.name3)
console.log(attributes3.dr3);
});
});
</script>
Underscore solution:
_.map(json, function(query) { //map the value of each property in json object
return _.object( //to an object created from array
query.split('&') //resulting from splitting the query at &
.map(function(keyval) { //and turning each of the key=value parts
return keyval.split('='); //into a 2-element array split at the equals.
);
})
The result of the query.split... part is
[ [ 'ts1', 'Hallo'], ['ts2', 'Hillarry'], ... ]
Underscore's _.object function turns that into
{ ts1: 'Hallo', ts2: 'Hillarry', ... }
The end result is
{
name1: { ts1: 'hHallo', ts2: 'Hillarry, ...},
name2: { ...
}
Now result can be obtained with object.name3.dr3.
Avoiding Underscore
However, if you hate Underscore or don't want to use it, what it's doing with _.map and _.object is not hard to replicate, and could be a useful learning exercise. Both use the useful Array#reduce function.
function object_map(object, fn) {
return Object.keys(object).reduce(function(result, key) {
result[key] = fn(object[key]);
return result;
}, {});
}
function object_from_keyvals(keyvals) {
return keyvals.reduce(function(result, v) {
result[v[0]] = v[1];
return result;
}, {});
}
:
var person={
"name1":"ts1=Hallo&ts2=Hillarry&ts3=Sting&ts4=Storm",
"name2":"st1=Hallo2&st2=Hillarry2&st3=Sting2&st4=Storm2",
"name3":"dr1=Hallo3&dr2=Hillarry3&dr3=Sting3&dr4=Storm3",
"name4":"ds1=Hallo4&ds2=Hillarry4&ds3=Sting4&ds4=Storm4"
}
var pN = person.name3;
var toSearch = 'dr3';
var ar = pN.split('&');
var result = '';
for(var i=0; i< ar.length; i++)
if(ar[i].indexOf(toSearch) >= 0 )
result=ar[i].split('=')[1];
console.log('result=='+result);

jquery each not working propertly while looping through

I am not able to figure out, why this code (only js) is not running - http://jsfiddle.net/fLEAw/
populateList();
populateList: function () {
var accData = [{ A: "A1" }, { B: "B1"}];
$.each(accData, function (index) {
alert(accData[index].Value)
});
}
You javascript/jquery code has multiple issues. have a look at this
var populateList = function () {
var accData = [{ A: "A1" }, { B: "B1"}];
$.each(accData, function (index) {
for(var value in accData[index]){
alert(accData[index][value])
}
});
}
populateList();
I would rather suggest you to rectify the issues your self and ask in comment.
http://jsfiddle.net/fLEAw/3/
You can use $.each to loop arrays and objects:
$.each(accData, function(i, obj) {
$.each(obj, function(k, value) {
alert(value);
});
});
I doubt you'll end up using alert, you probably want the values to do something with them, so you can put them in an array. Here's an alternative re-usable approach in plain JavaScript:
var values = function(obj) {
var result = [];
for (var i in obj) {
result.push(obj[i]);
}
return result;
};
var flatten = function(xs) {
return Array.prototype.concat.apply([], xs);
};
var result = flatten(accData.map(values));
console.log(result); //=> ["A1", "B1"]
Change
populateList: function () {
to
function populateList() {
Write:
populateList();
function populateList() {
var accData = [{
A: "A1"
}, {
B: "B1"
}];
var len = accData.length;
for (var i = 0; i < len; i++) {
$.each(accData[i], function (key, value){
//key will return key like A,B and value will return values assigned
alert(value)
});
}
}
Updated fiddle here.
Since your array element is object, try this solution:
var populateList = function () {
var accData = [{ A: "A1" }, { B: "B1"}];
$.each(accData, function (index) {
for(var ele in accData[index]){
alert(accData[index][ele]);
}
});
};
populateList();
Demo
try something like this
var accData = [{ A: "A1" }, { B: "B1"}];
$.each(accData, function (index,obj) {
$.each(obj, function(key, value) {
alert(key + '' + value);
});
});

Convert JSON empty array to empty string

I have some JSON that looks like this:
{
"ST": "Security",
"C1": "Login failures",
"C2": "1",
"C3": {},
"P1": "2",
"P2": "administrator",
"P3": {},
"P4": {},
"DESCR": "failed login attempts",
"SID": "88",
"AV": "NO",
"SC": "0",
"CN": {}
}
I also have this jQuery loop to filter out values:
$.each(data, function(key, value) {
var innerArr = [];
$.each(value, function(innerKey, innerValue) {
innerArr.push(innerValue);
});
valueArr.push(innerArr);
});
The problem is that on items C3, P3, P4 & CN in my example, the each loop is pushing the value [object Object] into my value collection.
Is there a way to make these items empty strings rather than objects?
You could use:
...
if(typeof innerValue == "object") innerValue = JSON.stringify(innerValue);
valueArr.push(innerValue);
....
The stringify method of the JSON object turns an object into a string. The empty object {} will turn in "{}". If you want to add an empty string instead, use:
if(typeof innerValue == "object"){
innerValue = JSON.stringify(innerValue);
if(innerValue == "{}") innerValue = "";
}
valueArr.push(innerValue);
If you're 100% sure that your object is empty, you don't have to use JSON.stringify. typeof innerValue == "onject" would then be sufficient, to check whether you have to add "" instead of innerValue.
An alternative method to check whether an object is empty or not:
if(typeof innerValue == "object"){
var isEmpty = true;
for(var i in innerValue){
isEmpty = false;
break;
}
if(isEmpty) innerValue = "";
else {
//Object not empty, consider JSON.stringify
}
}
valueArr.push(innerValue);
$.each(data, function(key, value) {
var innerArr = [];
$.each(value, function(innerKey, innerValue) {
if (typeof innerValue == 'object') {
innerValue = '';
}
innerArr.push(innerValue);
});
valueArr.push(innerArr);
});
FYI, you can use .parseJSON function and get results easily
var obj = jQuery.parseJSON('{"ST":"Security"}');
alert( obj.ST === "Security" );
$.each(data, function(key, value) {
var innerArr = [];
$.each(value, function(innerKey, innerValue) {
innerValue = ($.isEmptyObject(innerValue)) ? '' : innerValue;
innerArr.push(innerValue);
});
valueArr.push(innerArr);
});
Edit:
If you didn't want to rely on jQuery's isEmptyObject() function, you could implement one yourself:
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
// Get the size of an object
var size = Object.size(myArray);
$.each(data, function(key, value) {
var innerArr = [];
$.each(value, function(innerKey, innerValue) {
innerArr.push(innerValue);
});
//valueArr.push(innerArr);
valueArr.push(innerArr.join());
});
What is the inside loop for? It loops on each single letter of the String values.
$.each(data, function(key, value) {
var innerArr = [];
if (jQuery.isEmptyObject(value)) {
value = '';
}
...
});
Anyway you can use jQuery.isEmptyObject() to test easily if value is an empty object and modify it to an empty string.

Categories

Resources