I have a servlet which talks with the database then returns a list of ordered (ORDER BY time) objects. At the servlet part, I have
//access DB, returns a list of User objects, ordered
ArrayList users = MySQLDatabaseManager.selectUsers();
//construct response
JSONObject jsonResponse = new JSONObject();
int key = 0;
for(User user:users){
log("Retrieve User " + user.toString());
JSONObject jsonObj = new JSONObject();
jsonObj.put("name", user.getName());
jsonObj.put("time", user.getTime());
jsonResponse.put(key, jsonObj);
key++;
}
//write out
out.print(jsonResponse);
From the log I can see that the database returns User objects in the correct order.
At the front-end, I have
success: function(jsonObj){
var json = JSON.parse(jsonObj);
var id = 0;
$.each(json,function(i,item) {
var time = item.time;
var name = item.name;
id++;
$("table#usertable tr:last").after('<tr><td>' + id + '</td><td width="20%">' + time +
'</td><td>' + name +
'</td></tr>');
});
},
But the order is changed.
I only noticed this when the returned list has large size (over 130 users).
I have tried to debug using Firebug, the "response tab" in Firebug shows the order of the list is different with the log in the servlet.
Did i do anything wrong?
EDIT: Example
{"0":{"time":"2011-07-18 18:14:28","email":"xxx#gmail.com","origin":"origin-xxx","source":"xxx","target":"xxx","url":"xxx"},
"1":{"time":"2011-07-18 18:29:16","email":"xxx#gmail.com","origin":"xxx","source":"xxx","target":"xxx","url":"xxx"},
"2":
,...,
"143":{"time":"2011-08-09 09:57:27","email":"xxx#gmail.com","origin":"xxx","source":"xxx","target":"xxx","url":"xxx"}
,...,
"134":{"time":"2011-08-05 06:02:57","email":"xxx#gmail.com","origin":"xxx","source":"xxx","target":"xxx","url":"xxx"}}
As JSON objects do not inherently have an order, you should use an array within your JSON object to ensure order. As an example (based on your code):
jsonObj =
{ items:
[ { name: "Stack", time: "..." },
{ name: "Overflow", time: "..." },
{ name: "Rocks", time: "..." },
... ] };
This structure will ensure that your objects are inserted in the proper sequence.
Based on the JSON you have above, you could place the objects into an array and then sort the array.
var myArray = [];
var resultArray;
for (var j in jsonObj) {
myArray.push(j);
}
myArray = $.sort(myArray, function(a, b) { return parseInt(a) > parseInt(b); });
for (var i = 0; i < myArray.length; i++) {
resultArray.push(jsonObj[myArray[i]]);
}
//resultArray is now the elements in your jsonObj, properly sorted;
But maybe that's more complicated than you are looking for..
As mentioned by ghayes , json objects are unordered.
There are multiple solutions to this problem.
You can use array and the sort it to get the ordered list.
You can use gson library to get the desired order of elements.
I would prefer the second option as it is easy to use.
As JSONObject is order less and internally uses Hashmap. One way to use it to download the all classes from org.json and use in your project directly by changing the internal HashMap implementation to LinkedHashMap in JSONObject.java file. below is the sorted json files
https://github.com/abinash1/Sorted-Json-Object
Related
I want to create a dummy json data and use it for highChart.
This is how I am creating json array
var summaryData = {
WestWorld:[
{"Jan":7894},
{"Feb":7845},
{"March":5826},
{"April":7930},
{"May":1589},
{"June":7891},
{"July":9724},
{"August":7403},
{"September":5566},
{"October":7733},
{"November":1186},
{"December":4456}
],
EastWorld:[
{"Jan":7410},
{"Feb":9512},
{"March":7520},
{"April":8510},
{"May":9965},
{"June":72580},
{"July":147},
{"August":4489},
{"September":6685},
{"October":7036},
{"November":8852},
{"December":4569}
]
};
Now I intend to use this data for drawing charts.I am able to retrieve the keys by doing so
for (var key in summaryData){
console.log(summaryData[''+key+'']);
}
It is consoling an two arrays each of twelve objects.
Can I create this json object in a better way & minimize the if & for loop to get it's keys & value
You can setup your JSON like so:
var summaryData = {
WestWorld: {
"Jan":7894,
"Feb":7845,
...
},
EastWorld: {
"Jan":7410,
"Feb":9512,
...
}
};
This way you can access anything directly, without having to loop through the arrays in WestWorld and EastWorld. For example:
summaryData.WestWorld.Jan => 7894
summaryData has two objects that are arrays and in this case array of objects.
This will retrieve one array and its length
console.log((summaryData.EastWorld).length);
Show the first array element which is an object with a single key:value
console.log(summaryData.EastWorld[0]);
to get its value
console.log(summaryData.EastWorld[0].Jan);
A function to retrieve each key:value pair
function show(world) {
var len = (summaryData[world]).length;
var obj = "";
var ii = 0;
for (ii; ii < len; ii += 1) {
obj = summaryData[world][ii];
for (var key in obj) {
console.log(key + ' ==> ' + obj[key]);
}
}
}
show("WestWorld");
show("EastWorld");
To be a true JSON each string need to be double quoted
check with an online JSON Validation..
I have two data structures (they are much longer, these are just excerpts)
var data = [
{count: 6, zip: "78705"},
{count: 4, zip: "78754"},
{count: 33, zip: "78757"}
]
var txcodes = [
{county: "SWISHER", code: "437"},
{county: "TARRANT", code: "439"},
{county: "TAYLOR", code: "441"},
{county: "TRAVIS", code: "453"}
]
I have written code that successfully goes through “data” and takes the zipcode and retrieves the corresponding county (from an external website via HTTP request). It returns a structure that looks like
results = {
TRAVIS: 8,
TAYLOR: 1
}
(8 and 1 are examples of counters for how many times a zipcode from data occurs…basically a running count).
What I need to do next is use the keys from results to look up what the corresponding code in txcodes is. How do I do this?
var currentCounty = str.result[0].County
returns the county from results.
console.log(txcodes[i].county + " " + txcodes[i].code)
prints the county & code from txcodes.
I’m a little confused on how to do this. It seems like a relatively simple concept but I can’t seem to get the desired result. Can someone please point me in the right direction?
If county names are unique and if you are going to be making repeated lookups, you should build a "map" of the codes out of the array:
var txcodesByCounty = txcodes.reduce(function(p, c) {
p[c.county] = c.code;
return p;
}, {});
You can then look up codes directly from this map.
Build a lookup map like this :
var lookupMap = {};
for (var i = 0; i < txcodes.length; i++) {
var element = txcodes[i];
lookupMap[element.county] = element;
}
Then you can simply do this to print the desired output :
console.log(lookupMap[currentCounty].county + " " + lookupMap[currentCounty].code);
If the county in your result is only available as a key, you'll need to for..in, Object.keys or Object.getOwnPropertyNames to access them.
After, access the details via a map as others have suggested
var county, found = [];
for (county in results)
found.push(map[county]);
So what you get back from your HTTP request is a simple object, and you need to access its property names. You can do that easily with Object.keys:
resultKeys = Object.keys(result);
This will give you an array of the object properties:
[ "TRAVIS", "TAYLOR" ]
You can easily iterate over this array now, and inside you ask your result object for its value:
for (var i = 0; i < resultKeys.length; i++) {
console.log(resultkeys[i] + ": " + result[resultkeys[i]]);
}
Using this technique, you can use for example underscore.js libary to easily filter for your desired data:
for (var i = 0; i < resultKeys.length; i++) {
console.log(_.filter(txcodes , function(key){ return txcodes.county== resultkeys[i]; }));
}
I have an object which comes back as part of a return data from a REST server. It is part of an item object.
(I don't have control over the REST server so I can't change the data received):
{
"Option:Color":"Red,Green,Blue,Orange",
"Option:Size":"Small,Medium,Large"
}
What I want to end up with is some control over this, so that I can display the results when a product is selected in my app. It will appear in a modal. I am using Marionette/Backbone/Underscore/JQuery etc. but this is more of a JavaScript question.
I have tried multiple ways of getting at the data with no success. I would like to be able to have the options in a nested array, but I'd be open to other suggestions...
Basically this kind of structure
var Color=('Red', 'Green', 'Blue', 'Orange')
var Size('Small', 'Medium', 'Large')
The Object structure is fine, just need to be able to translate it to an array and take out the 'Option' keyword
Important to mention that I have no idea what the different options might be when I receive them - the bit after Options: might be any form of variation, color, size, flavour etc.
Loop through the parsed JSON and create new keys on a new object. That way you don't have to create the var names yourself; it's automatically done for you, albeit as keys in a new object.
var obj = {
"Option:Color":"Red,Green,Blue,Orange",
"Option:Size":"Small,Medium,Large"
}
function processObj() {
var newObj = {};
for (var k in obj) {
var key = k.split(':')[1].toLowerCase();
var values = obj[k].split(',');
newObj[key] = values;
}
return newObj;
}
var processedObj = processObj(obj);
for (var k in processedObj) {
console.log(k, processedObj[k])
// color ["Red", "Green", "Blue", "Orange"], size ["Small", "Medium", "Large"]
}
Edit: OP I've updated the code here and in the jsfiddle to show you how to loop over the new object to get the keys/values.
Fiddle.
var json = {
"Option:Color":"Red,Green,Blue,Orange",
"Option:Size":"Small,Medium,Large"
};
var color = json['Option:Color'].split(',');
var size = json['Option:Size'].split(',');
Try this to do get a solution without hardcoding all the option names into your code:
var x = {
"Option:Color":"Red,Green,Blue,Orange",
"Option:Size":"Small,Medium,Large"
};
var clean = {};
$.each(x, function(key, val){ //iterate over the options you have in your initial object
var optname = key.replace('Option:', ''); //remove the option marker
clean[optname] = val.split(","); //add an array to your object named like your option, splitted by comma
});
clean will contain the option arrays you want to create
EDIT: Okay, how you get the names of your object properties like "color", which are now the keys in your new object? Thats the same like before, basically:
$.each(clean, function(key, val){
//key is the name of your option here
//val is the array of properties for your option here
console.log(key, val);
});
Of course we stick to jQuery again. ;)
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);
});
}
});
}
Description and Goal:
Essentially data is constantly generated every 2 minutes into JSON data. What I need to do is retrieve the information from the supplied JSON data. The data will changed constantly. Once the information is parsed it needs to be captured into variables that can be used in other functions.
What I am stuck in is trying to figure out how to create a function with a loop that reassigns all of the data to stored variables that can later be used in functions.
Example information:
var json = {"data":
{"shop":[
{
"carID":"7",
"Garage":"7",
"Mechanic":"Michael Jamison",
"notificationsType":"repair",
"notificationsDesc":"Blown Head gasket and two rail mounts",
"notificationsDate":07/22/2011,
"notificationsTime":"00:02:18"
},
{
"CarID":"8",
"Garage":"7",
"Mechanic":"Tom Bennett",
"notificationsType":"event",
"notifications":"blown engine, 2 tires, and safety inspection",
"notificationsDate":"16 April 2008",
"notificationsTime":"08:26:24"
}
]
}};
function GetInformationToReassign(){
var i;
for(i=0; i<json.data.shop.length; i++)
{
//Then the data is looped, stored into multi-dimensional arrays that can be indexed.
}
}
So the ending result needs to be like this:
shop[0]={7,7,"Michael Jamison",repair,"Blown Head gasket and two rail mounts", 07/22/2011,00:02:18 }
shop[1]={}
You can loop through your JSON string using the following code,
var JSONstring=[{"key1":"value1","key2":"value2"},{"key3":"value3"}];
for(var i=0;i<JSONstring.length;i++){
var obj = JSONstring[i];
for(var key in obj){
var attrName = key;
var attrValue = obj[key];
//based on the result create as you need
}
}
Hope this helps...
It sounds to me like you want to extract the data in the "shop" property of the JSON object so that you can easily reference all of the shop's items. Here is an example:
var json =
{
"data":
{"shop":
[
{"itemName":"car", "price":30000},
{"itemName":"wheel", "price":500}
]
}
},
inventory = [];
// Map the shop's inventory to our inventory array.
for (var i = 0, j = json.data.shop.length; i < j; i += 1) {
inventory[i] = json.data.shop[i];
}
// Example of using our inventory array
console.log( inventory[0].itemName + " has a price of $" + inventory[0].price);
Well, your output example is not possible. You have what is a list of things, but you're using object syntax.
What would instead make sense if you really want those items in a list format instead of key-value pairs would be this:
shop[0]=[7,7,"Michael Jamison",repair,"Blown Head gasket and two rail mounts", 07/22/2011,00:02:18]
For looping through properties in an object you can use something like this:
var properties = Array();
for (var propertyName in theObject) {
// Check if it’s NOT a function
if (!(theObject[propertyName] instanceof Function)) {
properties.push(propertyName);
}
}
Honestly though, I'm not really sure why you'd want to put it in a different format. The json data already is about as good as it gets, you can do shop[0]["carID"] to get the data in that field.