I know there are 1 million and 1 questions on this, but I cannot seem to find an answer.
I am receiving data via PHP as such
echo json_encode($result);
From a typical MYSQL query.
I get the result back like this in the console.
[{"id" : "1", "name" : "bob"}]
I am trying to use $.each to iterate through this so I can process my results but I only get errors, undefineds or 0[object Object].. things like that.
My goal is to append each value to a input box (retrieving data from a table to put into an edit box).
$.post('getstuff.php', { id : id } function(data){
$.each(data), function(k,v){
$('input[name= k ]').val(v);
});
});
As you can see i was hoping it was as simple as a key=>value pair but apparantly not. I have tried parsing, stringifiying.. really I am lost at this point. I also cannot tell $.post that I am using JSON because I am using a more arbitrary function, but am just posting that as my example.
Edit
var retrievedData = JSON.parse(data);
$.each(retrievedData, function(k,v){
for (var property in retrievedData) {
if (retrievedData.hasOwnProperty(property)) {
console.log(k);
console.log(v);
console.log(property);
//$('input[name= k ]').val(v);
}
}
});
In your second code sample, retrievedData is an array, which you iterate using jQuery $each...
$.each(retrievedData, function(k, v) {
OK so far. But then you try to iterate retrievedData again like an object, which it isn't. This is why you are getting undefined messages in the console
for (var property in retrievedData) {
if (retrievedData.hasOwnProperty(property)) {
console.log(k);
console.log(v);
console.log(property);
//$('input[name= k ]').val(v);
}
}
On the inner loop you should be iterating v not retrievedData. On each pass of $each v will be an object.Try this:
$.each(retrievedData, function(k,v){
for (var key in v) {
if (v.hasOwnProperty(key)) {
console.log("key: " + key);
console.log("value: " + v[key]);
}
}
});
You should do some type checking that v is an object first and catch any errors.
Use either :
$.ajax({
'dataType' : 'json'
});
Or
$.getJSON
Or if you want to use $.post, just do in your success function :
var good_data = JSON.parse(data);
$.each(good_data, function(k,v) {
$('input[name= k ]').val(v);
});
Answering your question based on your comments on other answer.
My assumption is you are getting data as JSON,if not you need to parse it,for that you can use JSON.parse(string).
Here I'm using Underscore.js
var data=[{"id" : "1", "name" : "bob"}]
$(data).each(function(ind,obj){
var keys=_.keys(obj);
$(keys).each(function(i,ke){
console.log(ke)
console.log(obj[ke]);
})
});
Here is JSFiddle of working code
First you need to define you're expecting JSON in your POST request - http://api.jquery.com/jQuery.post/
Then you need to iterate through the response.
$.post('getstuff.php', { id : id } function(data){
//Assuming you get your response as [{"id" : "1", "name" : "bob"}], this is an array
//you need to iterate through it and get the object and then access the attributes in there
$.each(data), function(item){
$('input[name=' + item.name + ']').val(item.id);
});
}, 'json');
EDIT
If you want to iterate over the properties of the objects returned, you need to put another loop inside the $.each
for (var property in item) {
if (object.hasOwnProperty(property)) {
// do stuff
}
}
More about it here - Iterate through object properties
EDIT 2
To address the solution you've posted. You've used the wrong variable names. Here's a working fiddle - http://jsfiddle.net/EYsA5/
var $log = $('#log');
var data = '[{"id" : "1", "name" : "bob"}]'; //because we're parsing it in the next step
var retrievedData = JSON.parse(data);
for (var parentProp in retrievedData) { //this gets us each object in the array passed to us
if (retrievedData.hasOwnProperty(parentProp)) {
var item = retrievedData[parentProp];
for (var property in item) { //this gives us each property in each object
if (item.hasOwnProperty(property)) {
console.log(item[property]);
$log.prepend("<br>");
$log.prepend("Property name is - " + property);
$log.prepend("<br>");
$log.prepend("Value of property is - " + item[property]);
//do stuff
}
}
}
};
Related
I am banging my head trying to figure this out. And it should not be this hard. I am obviously missing a step.
I am pulling data from: openaq.org
The object I get back is based on a JSON object.
For now, I am using jQuery to parse the object and I am getting to the sub portion of the object that hold the specific parameter I want but I can't get to the specific key,value pair.
The object does not come back in the same order all the time. So when I tried to originally set up my call I did something like
obj.results.measurements[0].
Well since the obj can come back in an random order, I went back to find the key,value pair again and it was the wrong value, throwing my visual off.
That said, I have looked at use jQuery's find() on JSON object and for some reason can not get what I need from the object I am given by openaq.org.
One version of the object looks like this:
{"meta":{"name":"openaq-api","license":"CC BY 4.0d","website":"https://u50g7n0cbj.execute-api.us-east-1.amazonaws.com/","page":1,"limit":100,"found":1},"results":[{"location":"Metro Lofts","city":null,"country":"US","coordinates":{"latitude":39.731,"longitude":-104.9888},"measurements":[{"parameter":"pm10","value":49.9,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"pm1","value":24,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"um100","value":0,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um025","value":0.28,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um010","value":4.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"pm25","value":41.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"}]}]}
I am trying to get the "pm25" value.
The code I have tried is this:
function getAirQualityJson(){
$.ajax({
url: 'https://api.openaq.org/v2/latest?coordinates=39.73915,-104.9847',
type: 'GET',
dataType: "json"
// data: data ,
}).done(function(json){
console.log("the json is" + JSON.stringify(json));
console.log("the json internal is" + JSON.stringify(json.results));
var obj = json.results;
var pm25 = "";
//console.log(JSON.stringify(json.results.measurements[0]["parameter"]));
$.each(json.results[0], function(i,items){
//console.log("obj item:" + JSON.stringify(obj[0].measurements));
$.each(obj[0].measurements, function(y,things){
//console.log("each measurement:" + JSON.stringify(obj[0].measurements[0].value));//get each measurement
//pm 2.5
//Can come back in random order, get value from the key "pm25"
// pm25 = JSON.stringify(obj[0].measurements[2].value);
pm25 = JSON.stringify(obj[0].measurements[0].value);
console.log("pm25 is: " + pm25); // not right
});
});
//Trying Grep and map below too. Not working
jQuery.map(obj, function(objThing)
{ console.log("map it 1:" + JSON.stringify(objThing.measurements.parameter));
if(objThing.measurements.parameter === "pm25"){
// return objThing; // or return obj.name, whatever.
console.log("map it:" + objThing);
}else{
console.log("in else for pm25 map");
}
});
jQuery.grep(obj, function(otherObj) {
//return otherObj.parameter === "pm25";
console.log("Grep it" + otherObj.measurements.parameter === "pm25");
});
});
}
getAirQualityJson();
https://jsfiddle.net/7quL0asz/
The loop is running through I as you can see I tried [2] which was the original placement of the 'pm25' value but then it switched up it's spot to the 3rd or 4th spot, so it is unpredictable.
I tried jQuery Grep and Map but it came back undefined or false.
So my question is, how would I parse this to get the 'pm25' key,value. After that, I can get the rest if I need them.
Thank you in advance for all the help.
You can use array#find and optional chaining to do this,
because we are using optional chaining, undefined will be returned if a property is missing.
Demo:
let data = {"meta":{"name":"openaq-api","license":"CC BY 4.0d","website":"https://u50g7n0cbj.execute-api.us-east-1.amazonaws.com/","page":1,"limit":100,"found":1},"results":[{"location":"Metro Lofts","city":null,"country":"US","coordinates":{"latitude":39.731,"longitude":-104.9888},"measurements":[{"parameter":"pm10","value":49.9,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"pm1","value":24,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"um100","value":0,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um025","value":0.28,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um010","value":4.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"pm25","value":41.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"}]}]}
let found = data?.results?.[0]?.measurements?.find?.(
({ parameter }) => parameter === "pm25"
);
console.log(found);
You can iterate over measurements and find the object you need:
const data = '{"meta":{"name":"openaq-api","license":"CC BY 4.0d","website":"https://u50g7n0cbj.execute-api.us-east-1.amazonaws.com/","page":1,"limit":100,"found":1},"results":[{"location":"Metro Lofts","city":null,"country":"US","coordinates":{"latitude":39.731,"longitude":-104.9888},"measurements":[{"parameter":"pm10","value":49.9,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"pm1","value":24,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"um100","value":0,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um025","value":0.28,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um010","value":4.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"pm25","value":41.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"}]}]}';
const json = JSON.parse(data);
let value = null;
const measurements = json?.results?.[0]?.measurements ?? null;
if(measurements)
for (const item of measurements)
if (item.parameter === 'pm25') {
value = item.value;
break;
}
if (value) {
// here you can use the value
console.log(value);
}
else {
// here you should handle the case where 'pm25' is not found
}
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);
});
}
})
Ok, i know it might be simple for some guys, but i am trying this for hours and have no success till now.
if i have data in this array
var tDataValues = {
id: "TenantID",
text: "FullName",
username: "Username",
cnic: 'CNIC'
}
i am sending this variable to the function
commonSelect2Templating(selector,url,tDataValues,minInputLength,placeholder);
Note: I'm using Jquery Select2 (Sharing if it can help my question to understand.)
Then in that function in results Section i am trying to assign values
results: function(data, page) {
var newData = [];
var length = data.length + 1;
for(var i = 0; i<=length; i++){
}
$.each(data, function (index,value) {
newData.push({
id: value[tDataValues.id], //id part present in data
text: value[tDataValues.text] //string to be displayed
});
});
return { results: newData };
}
This is the data coming from the Server:
[{"TenantID":"13","FullName":"Rameez Hassana","Username":"Rameez","CNIC":"16141-6321136-1"},{"TenantID":"14","FullName":"Syed Haider Hassan","Username":"pakistanihaider","CNIC":"17301-5856870-1"},{"TenantID":"15","FullName":"Demo Tenant No 1","Username":"tn1","CNIC":"15165-6156685-6"}]
Coming to the The Problem:
Right now all the magic is happening here.
$.each(data, function (index,value) {
newData.push({
id: value[tDataValues.id], //id part present in data
text: value[tDataValues.text] //string to be displayed
});
Its Telling the code which is id and which is text, and it is working perfectly fine.
Now the Problem here is function i am trying to make is Common Function for the select2,
and if i have more values from db, like now i am getting from database how to make a loop and set those values one by one to its proper context.
e-g
tDataValues holds the fieldName cnic and server is sending the fieldName CNIC
so how to make a loop that if cnic exist in both then it should simply assign,
i can do that manually
newData.push({
cnic: value[tDataValues.cnic]
});
But like this it can not be a common function.
i can not simply make a logic how to implement this. did tried for hours but no success so far :(
Try:
for(var key in tDataValues) {
newData.push({ key: value[tDataValues[key]]});
}
Update:
then create an object first and push it to the array:
for(var key in tDataValues) {
var obj = {};
obj[key] = value[tDataValues[key]];
newData.push(obj);
}
check this, hope it helps
var mainData =[{"TenantID":"13","FullName":"Rameez Hassana","Username":"Rameez","CNIC":"16141-6321136-1"},{"TenantID":"14","FullName":"Syed Haider Hassan","Username":"pakistanihaider","CNIC":"17301-5856870-1"},{"TenantID":"15","FullName":"Demo Tenant No 1","Username":"tn1","CNIC":"15165-6156685-6"}];
var newData =[];
for(var i =0;i<mainData.length;i++){
for(var key in mainData[i]) {
var tempObj ={};
tempObj[key] = mainData[i][key];
newData.push(tempObj);
}
}
OUTPUT IS : [{"TenantID":"13"},{"FullName":"Rameez Hassana"},{"Username":"Rameez"},{"CNIC":"16141-6321136-1"},{"TenantID":"14"},{"FullName":"Syed Haider Hassan"},{"Username":"pakistanihaider"},{"CNIC":"17301-5856870-1"},{"TenantID":"15"},{"FullName":"Demo Tenant No 1"},{"Username":"tn1"},{"CNIC":"15165-6156685-6"}]
I am getting the data from an API using JavaScript.
The statement console.log(json[0]) gives the result:
{"id":"1","username":"ghost","points":"5","kills":"18","xp":"10","diamonds":"0","level":"1","missionscomplete":"1"}
Now I am trying to print the individual elements of this dictionary. How do I do this ? My code is below:
function loadLeaderboard(){
$.get("http://localhost:8888/l4/public/api/v1/getLeaderboard",function(data){
var json = $.parseJSON(data);
console.log(json[0]);
$.each(json[i], function(key, data) {
console.log(key + ' -> ' + data);
});
});
}
EDIT:
The value of data as returned by the API is
["{\"id\":\"1\",\"username\":\"ghost\",\"points\":\"5\",\"kills\":\"18\",\"xp\":\"10\",\"diamonds\":\"0\",\"level\":\"1\",\"missionscomplete\":\"1\"}","{\"id\":\"2\",\"username\":\"seconduser\",\"points\":\"0\",\"kills\":\"3\",\"xp\":\"0\",\"diamonds\":\"0\",\"level\":\"0\",\"missionscomplete\":\"0\"}","{\"id\":\"3\",\"username\":\"goat\",\"points\":\"12\",\"kills\":\"13\",\"xp\":\"14\",\"diamonds\":\"10\",\"level\":\"10\",\"missionscomplete\":\"4\"}"]
The value in json after the operation var json = $.parseJSON(data); is
["{"id":"1","username":"ghost","points":"5","kills":…diamonds":"0","level":"1","missionscomplete":"1"}", "{"id":"2","username":"seconduser","points":"0","ki…diamonds":"0","level":"0","missionscomplete":"0"}", "{"id":"3","username":"goat","points":"12","kills":…amonds":"10","level":"10","missionscomplete":"4"}"]
You can just use stringify method of JSON-
console.log(JSON.stringify(json[0]));
Update
Your JSON data is a mess. It's not in the format you want. It should be an array of objects, but instead it is an array of strings, where each of those strings is the JSON representation of one of your user objects.
You could decode this in your JavaScript code, but you shouldn't have to. The JSON API should be fixed to generate a reasonable JSON object.
I don't know what language your server code is in, but it must be doing something like this pseudocode:
array = []
for each userObject in leaderBoard:
userJson = toJSON( userObject )
array.push( userJson )
jsonOutput = toJSON( array )
Instead, the code should look more like this:
array = []
for each userObject in leaderBoard:
array.push( userObject )
jsonOutput = toJSON( array )
In other words, the way to generate the JSON you want in most languages is to create an object or array with the structure you need, and then call the language's toJSON function (or whatever function you use) on that object or array. Let it generate all of the JSON in one fell swoop. Don't generate JSON for each individual element of your array and then generate JSON again for the entire array as a whole. That gives you an array of strings where you want an array of objects.
Original answer
What you're asking for is not what you really want to do.
Your JSON response returns an array of user objects, correct? That's why json[0] is a single object.
You probably want to loop over that array, but you don't loop over the individual objects in the array. You simply reference their properties by name.
Also, instead of using $.get() and $.parseJSON(), you can use $.getJSON() which parses it for you.
And one other tip: don't put the hostname and port in your URL. Use a relative URL instead, and then you can use the same URL in both development and production.
So for test purposes, let's say you want to log the id, username, and points for each user in your leaderboard JSON array. You could do it like this:
function loadLeaderboard() {
var url = '/l4/public/api/v1/getLeaderboard';
$.getJSON( url, function( leaders ) {
// leaders is an array of user objects, so loop over it
$.each( leaders, function( i, user ) {
// get the properties directly for the current user
console.log( user.id, user.username, user.points );
});
});
}
json[0] is an object, so you want to loop over the keys:
var o = json[0];
for (var key in o) {
if (o.hasOwnProperty(key)) {
console.log(key, o[key]);
}
}
Working fiddle: http://jsfiddle.net/UTyDa/
jQuery.each() is probably the easiest way, check this out: http://api.jquery.com/jQuery.each/
eg
$.each(json[0], function(key, data) {
console.log(key + ' -> ' + data);
});
EDIT:
What's the result of the following?
function loadLeaderboard(){
$.get("http://localhost:8888/l4/public/api/v1/getLeaderboard",function(data){
var json = $.parseJSON(data);
console.log(json[0]);
for(var i = 0; i < json.length; i++) {
$.each(json[i], function(key, data) {
console.log(key + ' -> ' + data);
});
}
});
}
EDIT 2: 'data' returned as array.
function loadLeaderboard(){
$.get("http://localhost:8888/l4/public/api/v1/getLeaderboard", function(data){
for(var i = 0; i < data.length; i++) {
var json = $.parseJSON(data[i]);
console.log('Data for index: ' + i);
$.each(json, function(key, val) {
console.log(key + ' -> ' + val);
});
}
});
}
{
"id":["123"],
"optionid_123":"98"
}
I have the id as a variable, but from that how can I get the optionid_*? I tried a few things, but nothing seems to work. The each is inside of the appropriate function and jsonid contains the correct value. Here is my attempt at accessing the value 98 which doesn't work:
$.each(data.id,function(){
var jsonid = this;
console.log( data.optionid_+jsonid ); // doesn't work
});
You can use Bracket notation:
console.log( data['optionid_' + jsonid] );
I think your loop with data.id is not correct. That is
$.each(data.id, function() {..})
is incorrect.
For example if you data looks like following:
var data = [{
"id":["123"],
"optionid_123":"98"
},
{
"id":["456"],
"optionid_456":"99"
}];
Then you need to loop over data and get your required property.
$.each(data, function(index, val) {
var jsonid = val.id[0]; // as val.id is array so you need [0] to get the value
console.log(val['optionid_' + jsonid]); // bracket notation used
});
DEMO