.each parse JSON returns undefined - javascript

Hi I have the following codes:
$.ajax({'type':'POST', 'url':'https://www.123.com/site/gethistory',
'data':{'a': this.username, 'b': username},
'success':function(history){
alert(history);
var codes = jQuery.parseJSON(history);
$.each(codes, function(key, value) {
alert(key);
}); //each
},
'error':function(){
}
}); //ajax
Right now the key is undefined. And i tried to alert(value.text), it still gives me undefined.
history is alerted as this:
[{"demo":{"text":"hi
man","time":"1380167419"},"admin":{"text":"hi","time":"1380167435"},"demo":{"text":"this
works flawless now.","time":"1380167436"},"demo":{"text":"we are
basically done with this/","time":"1380167443"}}]

It works fine in this fiddle. However, there is a problem with your JSON.
Although it is syntactically correct, it is structured such that you are returning an array of one object with a number of properties all with the same name:
[
{ "demo":{
"text":"hi man",
"time":"1380167419"
},
"admin":{
"text":"hi",
"time":"1380167435"
},
"demo":{
"text":"this works flawless now.",
"time":"1380167436"
},
"demo":{
"text":"we are basically done with this/",
"time":"1380167443"
}
}
]
Each successive demo will overwrite the previous one, so you'll only see the last demo property.

Looks like there is something wrong with your JSON. Try alert codes and make sure the parsed JSON is in the right format, i.e key/value pairs

no need to use jQuery to parse JSON. Just var codes = JSON.parse(history)
$.each(codes, function(k, v){
console.log(v )
});

Related

Object.keys(data).forEach does not loop

I try to to get a value form json object.
var data={
"1":[{"departmentID":1,"departmentName":"Adminstration","branchId":1,"branchName":"ABC"}],
"2":[{"departmentID":2,"departmentName":"HR","branchId":2,"branchName":"DEF"}]
};
Object.keys(data).forEach(function(element, key, _array) {
console.log("branchId: "+element+" "+"BranchName : "+data[element][key].branchName)
for(dept of data[element]) {
console.log("Department name : "+dept.departmentName)
}
});
Here output is : the first result only and throws branchName is undefined exception.
But if the json object has multi object,its working fine.
var data={
"1":[{"departmentID":1,"departmentName":"Adminstration","branchId":1,"branchName":"ABC"}],
"2":[{"departmentID":2,"departmentName":"HR","branchId":2,"branchName":"XYZ"},
{"departmentID":3,"departmentName":"Food","branchId":2,"branchName":"XYZ"}]
}
I think, since I'm new to javascript, I couldn't solve. I tried a lot of reference to solve this problem, but I could not. Please try to solve this. Thanks in advance.
he first result only and throws branchName is undefined exception.
You need to replace
data[element][key].branchName
with
data[element][0].branchName
Because
element is the key "1",
so data[element] becomes [{"departmentID":1,"departmentName":"Adminstration","branchId":1,"branchName":"ABC"}],
data[element][0] becomes {"departmentID":1,"departmentName":"Adminstration","branchId":1,"branchName":"ABC"}
finally data[element][0].branchName is "ABC"
You have something mixed with your keys and indexes.
You can use Object.values (ES8 only) to get exact the values and left the keys part. Then iterate over them and make your strings.
const data = {
"1":[{"departmentID":1,"departmentName":"Adminstration","branchId":1,"branchName":"ABC"}],
"2":[{"departmentID":2,"departmentName":"HR","branchId":2,"branchName":"DEF"}]
}
Object.values(data).forEach(function(values) {
values.forEach(value => {
console.log(`branchId: ${value.branchId} BranchName: ${value.branchName} Department Name: ${value.departmentName}`);
});
});

Append data acquired from JSON to a Raphael object

Solved the question on my own, see answer
Using jQuery 3.2.1 and Raphael 2.1.1, if this matters
In my Raphael .js I first create some objects without any data and push them into an array, e. g. (.attr omitted):
var objarr = [];
var obj1 = rsr.path("M ... z");
objarr.push(obj1);
After this, I want to take data from a JSON file (an array named "regions" of multiple entries that consist of multiple key-value pairs (validated through JSONLint) and append it as data by id. It looks like this:
{
"regions": [{
"id": "0",
"var1": "foo1",
"var2": "bar1",
},
{
"id": "1",
"var1": "foo2",
"var2": "bar2",
},
// And so on for every object
]
}
I use the following code (localhost is used because otherwise I get a cross-access error:
for (var i = 0; i < objarr.length; i++)
{
var jq = $.getJSON("http://localhost:8000/data.json",{id: +i},function(t){
console.log( "success" );
})
.done(function(objdata){
console.log("success2");
$.each(objdata.regions, function(key, val){
objarr[i].data(key,val);
});
})
.fail(function(t){
console.log("error");
})
.always(function(t){
console.log("complete");
});
}
The console gives me both successes, but after this I get an error "Cannot read property 'data' of undefined". alert(key) and alert(val) give 0 and [object Object] respectively for every call. I tried adding the following to .done:
var items = [];
$.each(objdata.regions, function(key, val){
items.push("id" + key + ":" + val);
console.log(items);
});
The result was a string that went ["id0:[object Object]"],["id0:[object Object]", "id1:[object Object]"] and so on until it had objarr.length ids, repeating the needed amount of times. If I add [i] to objdata.regions, I get no console messages about items[] content at all.
I also found two somewhat closely related questions ("1" and "2"), checked the jQuery documentation for .getJSON(); and Raphael documentation for Element.data();. I've tried the following to check validity of my calls:
console.log(objdata) in the beginning of .done -- returns full base object of JSON data
console.log(objdata.regions) in the beginning of .done -- returns array of objects of JSON data
console.log(objdata.regions[i]) in the beginning of .done -- returns undefined
console.log(objdata.regions[0]) in the beginning of .done -- returns first object (works for every object)
I've used objdata.regions[0] in the snippet with items[] and the adding seems to work properly (console shows the keys and values being added to the array). However, it still doesn't work with objarr[i].data(key,val) (as well as ""+key and "$key").
I have two questions:
1. How do I acquire the key-value pairs properly while looping?
2. How do I append these pairs as data to a Raphael object?
I moved the for loop inside .done() and everything is appended successfully:
.done(function(objdata){
for (var i = 0; i < objarr.length; i++)
{
console.log("success2");
$.each(objdata.regions[i],function(key, val){
objarr[i].data(key, val);
});
}
})

Parse JSON in Javascript from PHP

I am passing a json encoded string in an ajax response to my Javascript. When I console.log the json, after JSON.Parse, it looks like the following:
[
{"732":
{
"doctor_name":"First M. Last ",
"degree":"MD"
}
},
{"377":
{
"doctor_name":"First M. Last ",
"degree":"MD"
}
},
{"1092":
{
"doctor_name":"First M. Last",
"degree":"DO"
}
},
{"759":
{
"doctor_name":"First M. Last",
"degree":"MD"
}
},
{"1628":
{
"doctor_name":"First M. Last",
"degree":"DO"
}
}
]
I need to access each one of these objects without knowing the ids (in this case "732", "377", "1092", "759", etc.)
Not sure if my data is even structured properly but I cannot even use Object.keys(obj) as it returns an error of a non-object property.
The way I am structuring my PHP array is as follows:
foreach ($doctors as $group){
$doctor_results[][(int)$group->prac_id]=array(
'doctor_name' => (string)$group->name,
'degree' => (string)$group->degree,
);
} // end foreach
I want each array id to be used as the key, not sure if this makes much sense.
TYIA
You most likely want your PHP to look like:
foreach ($doctors as $group){
$doctor_results[(int)$group->prac_id]=array(
'doctor_name' => (string)$group->name,
'degree' => (string)$group->degree,
);
} // end foreach
Note the missing [], which would imply pushing an item onto a numeric array. The second set of brackets in your example is suggesting to PHP that the numeric element created should be an associative array with an item with the 'prac_id' as a key. PHP is automatically creating that associative array, creating the structure with your key nested one level further in than you want for being able to grab an item by 'prac_id' by simple key access in JavaScript. As is, you'd need a nested loop like in Darren's answer.
I heavily agree with the comments posted by Marty and Six Fingered Man, but if you wanted to loop through the json, this would work:
jQuery.each(obj, function(index, data){
jQuery.each(data, function(id, fields){
console.log(id); // returns the ID's of the objects: 732, 377,....etc
console.log(fields); // returns the fields for each object. (doctor_name & degree)
});
});
JSFiddle Demo
[
{prac_id:"732",data:
{
"doctor_name":"First M. Last ",
"degree":"MD"
}
},...]
foreach ($doctors as $group){
$doctor_results[][(int)$group->{'prac_id'}]=array(
'doctor_name' => (string)$group->{'data'}->{'name'},
'degree' => (string)$group->{'data'}->{'degree'},
);
} // end foreach
Your ajax response is array of OBJECT. If you encode it by json_encode($array), your ajax response is OK. You can check your ajax response here : http://json.parser.online.fr/
So I think you can modify your ajax call. You can just add this dataType: 'json' in your ajax. It will automatically handle your JSON response.
$.ajax({
url: 'your_ajax_url',
data: 'data',
dataType: 'json',
success: function(data)
{
$.each(data, function(index, obj){
$.each(obj, function(id, nested_obj){
console.log("ID: "+id);
console.log("doctor name: "+nested_obj['doctor_name']+",degree:"+ nested_obj['degree'] );
});
});
}
)}

Getting first object inside JSON

I'll cut straight to the chase. I'm getting a json object with another object inside of it like so:
function getName(summonerName, region) {
LolApi.Summoner.getByName(summonerName, region, function(err, summoner) {
if(!err) {
console.log(summoner);
}
});
}
However, the result of this call is (let's stay summonerName is "tetsii"):
{ tetsii:
{ id: 51520537,
name: 'tetsii',
profileIconId: 23,
summonerLevel: 23,
revisionDate: 1408307600000
}
}
Now, I can access the id's and stuff with "console.log(summoner.tetsii.id)" for example, but because the summonerName (in this case "tetsii") can be anything, I prefer not to do it like so. So, my question is: how to access the first object inside a JSON or is there another way? And no, I can't get an array in this case afaik.
I would like to note that I've tried "console.log(summoner.summonerName.id)", but that doesn't yield results as summonerName is a string.
Thanks everybody
EDIT: Got the answer. By simply using summoner[summonerName].id I am able to grab the id. Thanks everyone for answers!
-Tetsii
By using Object.keys. For example, if you know that summoner will only have a single top-level key, you can get it with:
var summonerName = Object.keys(summoner)[0];
Obligatory browser support notice: IE < 9 does not support this out of the box, but you can use a polyfill provided in the MDN page as a compatibility shim.
There is no order in objects, so there's no guarantee you'll get the object you think, but using Object.keys and shift() you can do
var first = summoner[Object.keys(summoner).shift()];
If there is no way to return it as an array, the best idea is to iterate over the object properties as documented in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
The most important part is:
for (var prop in summoner) {
console.log("summoner." + prop + " = " + summoner[prop]);
}
Tested in console:
var summoner = { tetsii:
{ id: 51520537,
name: 'tetsii',
profileIconId: 23,
summonerLevel: 23,
revisionDate: 1408307600000
}
};
yields:
summoner.tetsii = [object Object]

Searching json array for a specific attribute

Actually I want to search an attribute's value in an json array for one of its child. Now one condition is that the attribute will not be there in all the child's of the array. This is my json array.
[{
"heading1":"heading1",
"heading2":"heading2",
"heading3":"heading3",
"heading4":"heading4",
"heading5":"heading5",
"heading6":"heading6"
},
{
"column1":65536,
"column2":"school",
"column3":"testing purpose",
"column4":"DESKTOP",
"column5":"ACTIVE",
"column6":true,
"column7":"a6cc82e0-a8d8-49b8-af62-cf8ca042c8bb"
},
{
"column1":98305,
"column2":"Nikhil",
"column3":"Test",
"column4":"LAPTOP",
"column5":"ACTIVE",
"column6":true,
"column7":"a6cc82e0-a8d8-49b8-af62-cf8ca042c8bb"
}]
So presently I am working with the each loop but like this
var obj = $.parseJSON(JSON.stringify(response));
$.each(obj, function () {
console.log("heading1", this['heading1']);
});
Here response comes from mserver and it is the json array
Now I want to know can I search for this attribute in the json array without using a loop in jQuery.
Based on your sample code what I understand you have is an array of objects and you want to find objects with one specific property and or value:
This will return true if the object has the property
var results= arr.filter(function(item){ return item.hasOwnProperty("column5"); });
Or you can perform additional action when you find the property:
arr.filter(function(item){
if (item.hasOwnProperty("column5")) {
return item["column5"] === 'demo 01'; //or item.column5 === 'demo 01'
}
return false;
});
This only works on IE9+ if you need this to run in older versions of IE, please follow the instructions under polyfill:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
The you can check like
var obj = $.parseJSON(response);
$.each(obj, function (index,value) {
if(typeof obj[index].heading2 !== "undefined")
{
alert(obj[index].heading2);
}
when in other object of array element not find then it returns undefined. and you can check like that.
you can check in this http://jsfiddle.net/gKRCH/
It's best to use a loop. But if the format of the JSON is regular, you could regex for the value in the response string.
I'm not recommending this method, just pointing out that it exists.
var value = "heading1";
if( (new RegExp('"' + value + '"')).test(response) ){
// Found value
};
Here, we take the required value, wrap it in quotation marks and search for it in the response.
This has several issues, such as:
It might find the pattern in a property name
If the value could contain regex special characters, they'll need escaping.
If your JSON contains values with escaped quotation marks, you could get a false positive from partial matches.
That's why it depends on you knowing the format of the data.
EDIT:
You can solve issue 2 by using this condition instead of regex. But it gives you less flexibility.
response.indexOf('"' + value + '"') !== -1
Try this,
$.each(object,function(key, value){
console.log(key);
console.log(value);
});
You can use this JS lib; DefiantJS (http://defiantjs.com). This lib extends the global object JSON with the method "search" - with which, you can perform XPath queries on JSON structures. Like the one you have exemplified.
With XPath expressions (which is standardised query language), you can find whatever you're looking for and DefiantJS will do the heavy-lifting for you - allowing your code to be neat and clean.
Here is the fiddle of this code:
http://jsfiddle.net/hbi99/q8xst/
Here is the code:
var data = [
{
"heading1": "heading1",
"heading2": "heading2",
"heading3": "heading3",
"heading4": "heading4",
"heading5": "heading5",
"heading6": "heading6"
},
{
"column1": 65536,
"column2": "school",
"column3": "testing purpose",
"column4": "DESKTOP",
"column5": "ACTIVE",
"column6": true,
"column7": "a6cc82e0-a8d8-49b8-af62-cf8ca042c8bb"
},
{
"column1": 98305,
"column2": "Nikhil",
"column3": "Test",
"column4": "LAPTOP",
"column5": "ACTIVE",
"column6": true,
"column7": "a6cc82e0-a8d8-49b8-af62-cf8ca042c8bb"
}
],
res = JSON.search( data, '//*[column4="DESKTOP"]' );
console.log( res[0].column2 );
// school

Categories