I've been struggling with this and need some help.
This is a sample of the JSON that would be returned to me. I have it assigned to a variable called result, so I can test it in my code. I'm not sure how else to fake the JSON being returned to me.
https://dl.dropboxusercontent.com/u/10842024/JSON.js
The JSON consists of two different objects, Line and Line2, each made up of multiple path (polyline) features.
I'm trying to create a Polyline object and add each one to a map using the ESRI JavaScript API. Here is the documentation for the Polyline object:
https://developers.arcgis.com/javascript/jsapi/polyline-amd.html#polyline2
require(["esri/geometry/Polyline"], function(Polyline) {
var polylineJson = {
"paths":[[[-122.68,45.53], [-122.58,45.55],
[-122.57,45.58],[-122.53,45.6]]],
"spatialReference":{"wkid":4326}
};
var polyline = new Polyline(polylineJson);
});
The JSON I get returned fits what the Polyline object needs:
"features": [
{
"attributes": {
"OBJECTID": 2368
},
"geometry": {
"paths": [
[
[
-123.94500566712864,
45.27071700030354
],
[
-123.9449701393585,
45.27069704962526
],
[
-123.94494162013,
45.27067958572745
],
[
-123.94489725722464,
45.2706251239781
],
[
-123.94489153421517,
45.27054128625377
]
]
]
}
},
But how can I loop through each feature and insert the JSON into the Polyline object so that it's formatted correctly?
I know I'm missing something because I can't figure out how to do it.
Something in that order I guess...
for (var i in result.results)
{
var features = result.results[i].features;
for (var j in features)
{
console.log(features[j].attributes.OBJECTID); // print OBJECTID
var geometry = features[j].geometry.paths;
for (var k in geometry)
{
console.log(geometry[k]); // print paths, arrays of points
var points = geometry[k];
for (var l in points)
console.log(points[l]); // print points
}
}
}
http://jsfiddle.net/e0dxn8ze/2/ open JavaScript console to see what goes
Here's an untested solution I just wrote.
// Get the JSON string
json_string = whaterver_function_gets_you_the_json();
// Parse JSON into JS
polys = JSON.parse(json_string);
// Loop through polys and create Polyline
polys.features.forEach(function(el) {
new Polyline(el.geometry);
});
Edit: Sorry I didn't see the JSON.js link. This solution should still work, you'd just have to adjust which object property you're looping through. For instance: result.results[0].features.forEach(function(el){}); or if you need to also loop through all the results you can just nest forEachs.
Related
I am trying to access objects that are nested within an array. I start with this JSON object (which was derived from an XML database output):
{"report":
{"date":"15 Apr 2016",
"metrics":
{"metric":
[
{"name":"Bank Angle",
"display_parent_group":"Bankfull",
"display_child_group":"SiteShape",
"tolerance":"0.05",
"visits":
{"visit":
[
{"visit_id":"3047","value": "0.47"},
{"visit_id":"2164","value": "0.55"},
{"visit_id":"1568","value": "0.72"},
{"visit_id":"3431","value": "0.12"},
{"visit_id":"2428","value": "0.44"},
{"visit_id":"1567","value": "0.49"}
]}},
{"name":"Bank Angle SD",
"display_parent_group":"Bankfull",
"display_child_group":"SiteShape",
"tolerance":"0.05",
"visits":
{"visit":
[
{"visit_id":"3047","value": "0.12"},
{"visit_id":"2164","value": "0.05"},
{"visit_id":"1568","value": "0.21"},
{"visit_id":"3431","value": "0.68"},
{"visit_id":"2428","value": "0.22"},
{"visit_id":"1567","value": "0.13"}
]}},
{"name":"Bankfull Area",
"display_parent_group":"Bankfull",
"display_child_group":"SiteSize","tolerance":"0.05",
"visits":
{"visit":
[
{"visit_id":"3047","value": "202"},
{"visit_id":"2164","value": "193"},
{"visit_id":"1568","value": "115"},
{"visit_id":"3431","value": "258"},
{"visit_id":"2428","value": "89"},
{"visit_id":"1567","value": "206"}
]}}
]
}
}
}
I then use underscore to extract a subset of metric objects:
var table_metric = JSONData.report.metrics.metric;
var target_metrics = _.where(table_metric, {
display_parent_group : 'Bankfull', display_child_group: 'SiteShape'
});
This results in an array with two nested objects. Where I'm having a problem is then accessing the array of objects which is nested inside visits.visit. If, for instance, I want to build an array of values associated with the key visit_id, and I try:
function buildVisitIDArray(target_metrics) {
var attrList = [];
for(var i=0; i<target_metrics.length; i++) {
var visit_records = target_metrics[i].visits[1];
console.log(visit_records);
for(visit_record in visit_records) {
attrList.push(_.pluck(visit_record, "visit_id"));
}
}
return attrList
}
I just get an array of undefined results. I've spent hours trying variations on the syntax to get at the nested "visit" objects, but I just can't seem to figure it out.
Any help is much appreciated for this novice!
In your buildVisitIDArray function, you are trying to get target_metrics[i].visits[1] as if it was an array, but it's actually an object, so you should use it this way:
function buildVisitIDArray(target_metrics) {
attrList = [];
for(var i=0; i<target_metrics.length; i++) {
var visit_records = target_metrics[i].visits; // Removed the array call ([1])
console.log(visit_records);
for(visit_record in visit_records) {
attrList.push(_.pluck(visit_records[visit_record], "visit_id"));
}
}
return attrList;
}
Hope it helps :)
You may also have an issue if you're not defining attrList with the var keyword somewhere else in your code.
Building on Andre's answer, you may want to change this line to be:
visit_records = target_metrics[i].visits.visit;
to go one layer deeper, then do a regular array for loop afterward.
This is my returned JSON:
{
//...
"results":[
{
//more properties...
"geometry":{
"lat":51.2244644,
"lng":0.7334215
}
},
//more results...
],
//...
}
Complete JSON
I want to get information from a json result returned without having to use a specific companies JS helper file, just using the pure result myself. I'm looking to isolate results lat and lng shown here:
"geometry":{
"lat":51.2244644,
"lng":0.7334215
}
It seems like I can use code similar to this to get my result:
var json = '{"result":true,"count":1}',
obj = JSON.parse(json);
alert(obj.count);
How can I get the first coordinates returned in the result so I can later store them in an input box? I don't mind using jQuery if it simplifies this.
You can get first coordinates like following.
var json = '{"results":[{"geometry":{"lat":51.2244644,"lng":0.7334215}}]}';
var first_coordinate = JSON.parse(json).results[0].geometry;
console.log(first_coordinate);
If you want to get all coordinates in an array then try like following.
var arr = $(JSON.parse(json).results).map(function () {
return this.geometry;
}).get();
console.log(arr);
USE like this after JSON parsing
co-ordiniates from DMS
myArray.results[0].annotations.DMS
co-ordinitates from gemotery
myArray.results[0].geometry
You need to loop the results to get all co-ordinates
A javascript data object (JSON notation) has been created with the following content:
"[
{"range":"Shape","values":[{"idx":0,"val":"Random"},{"idx":1,"val":"Line"},{"idx":2,"val":"Square"},{"idx":3,"val":"Circle"},{"idx":4,"val":"Oval"},{"idx":5,"val":"Egg"}]},
{"range":"Color","values":[{"idx":0,"val":"Red"},{"idx":1,"val":"Blue"},{"idx":2,"val":"Yellow"},{"idx":3,"val":"Green"},{"idx":4,"val":"Cyan"}]}
]"
In a next step the index of an ordinal value has to be found in this object. The function should find the index of the value 'Blue' in the range 'Color'.
So the function should have the meta scripting form
f("Color")("Blue")=1
What is the most elegant form to create such a function in the context of D3 and javascript?
Depending on your use case, it might make sense to convert the data structure to a different structure more suitable for direct access. E.g. you could convert your structure to
var data = {
Shape: ['Random', 'Line', ...],
// ...
};
and access it with
data['Shape'].indexOf('Line') // or data.Shape.indexOf('Line')
Or go even one step further and convert to
var data = {
Shape: {
Random: 0,
Line: 1,
// ...
},
// ...
};
and access it with
data['Shape']['Line'] // or data.Shape.Line
What the best solution is depends on the actual use case.
Converting the structure dynamically is pretty straight forward. Here is an example to convert it to the first suggestion:
var newData = {};
data.forEach(function(item) {
newData[item.range] =
item.values.map(function(value) { return value.val; });
});
This would also reduce redundancy (e.g. idx seems to correspond with the element index).
Would this work for you ?
var dataJson = '[ \
{"range":"Shape","values":[{"idx":0,"val":"Random"},{"idx":1,"val":"Line"},{"idx":2,"val":"Square"},{"idx":3,"val":"Circle"},{"idx":4,"val":"Oval"},{"idx":5,"val":"Egg"}]},\
{"range":"Color","values":[{"idx":0,"val":"Red"},{"idx":1,"val":"Blue"},{"idx":2,"val":"Yellow"},{"idx":3,"val":"Green"},{"idx":4,"val":"Cyan"}]}\
]';
var data = JSON.parse(dataJson);
for (each in data){
if ( (data[each].range) === 'Color'){
for (eachVal in data[each].values){
if (data[each].values[eachVal].val === 'Blue'){
alert(data[each].values[eachVal].idx);
}
}
} ;
}
And here is the JSFiddle for you too.
I'm new to JSON and Jquery, and I can't find how to extract the values of ProjectCode from this JSON string.
[
{
"ProjectID": 3,
"CLustomerCode": "XYZ001",
"ProjectCode": "YZPROJ1",
"Description": "Project1",
"IssueManager": "iant",
"NotificationToggle": false,
"ProjectStatus": null,
"Added": "/Date(1400701295853}/",
"Added By": "iant",
"Changed": "/Date(1400701295853)/",
"Changed By": "iant"
},
{
"ProjectID": 4,
"CustomerCode": "XYZ001",
"ProjectCode": "XYXPROJ2",
"Description": "Projecton:Project2",
"IssweManager": "iant",
"NotificationToggle": false,
"Projectstatus": null,
"Added": "lDate(1400701317980)/",
"AddedBy": "iant",
"Changed": "/Date(1400701317980)/",
"Changed By": "iant"
}
]
The string above is from a variable called data that is the return value from stringify. I expected to be able to do something like
string proj = data[i].ProjectCode;
but intellisense doesn't include any of the properties.
I know very little about JSON - any help appreciated.
Thanks for reading.
Use parseJSON:
var obj = jQuery.parseJSON("{ 'name': 'Radiator' }");
alert(obj.name);
You need to loop through each object returned in the response and get the ProjectCode property inside each one. Assuming the data variable is your JSON this should work:
$.each(data, function(i, obj) {
console.log(obj.ProjectCode);
});
Use JSON.parse():
var a; // Your JSON string
var b = JSON.parse(a); //Your new JSON object
//You can access Project code, use index i in b[i].ProjectCode in a loop
var projectCode = b[0].ProjectCode;
You should post the raw code so its easier to visualize this stuff. Since what you are looking for is the list of ProjectCodes (in this case - ["XYZPROJ1", "XYZPROJ2"]).
It seems like what we have is an array or list ([...]) of projects. Where each project has a ProjectID, CustomerCode, ProjectCode, Description and so on...
So lets assume data points at this JSON blob. Here is how you would go about accessing the ProjectCode:
// Access the "i"th project code
var p_i_code = data[i].ProjectCode;
// How many projects?
var num_projects = data.length; // since data is a list of projects
// Want the list of project codes back? (I use underscore.js)
var project_codes = _.map(data, function(project) {
return project.ProjectCode;
});
I have a JSON file that was converted from a csv and is too big to hand edit. Its' syntax is one large array I think. The data is from a group of routers and I aim to build router objects. The way the current CSV to JSON file is organized by each row and I want to pick out each router and have an object with router name, the all bandwidth measurements associated with that router.
How would you approach this? I'm attempting to take care of all of this when I iterate through the JSON file and when the router changes, I start a new instance of the router object. I'm a no longer a newb, just a slow learner. So would the next step be to create a router class with js and populate the class with what I pull out of my giant JSON array, or could/should I do with out the handwritten class and create all the objects on the fly? (can I create objects on the fly.
Current JSON (it goes on for pages, each router having a few hundred entries in the csv:
[
{
"Router": "RouterID1",
"TimeStamp": "2012/01/01 06:00:00",
"transferBytes": "23235",
"ReceivedBytes": "29903"
},
{
"Router": "RouterID1",
"TimeStamp": "2012/01/01 06:05:00",
"transferBytes": "21235",
"ReceivedBytes": "22103"
}
{
"Router": "RouterID2",
"TimeStamp": "2012/01/01 06:00:00",
"transferBytes": "23235",
"ReceivedBytes": "29903"
},
{
"Router": "RouterID2",
"TimeStamp": "2012/01/01 06:05:00",
"transferBytes": "21235",
"ReceivedBytes": "22103"
}
]
#amnotiam: the router types are gauranteed to be adjecent to each other
This might not be valid but here is the structure I think I'm going for:
[
{
"Router": "RouterID1"
"TimeStamp": array of timestamps
"transferBytes": array of bytes transferred for each timestamp
"ReceivedBytes": array of bytes received for each timestamp
},
{
"Router": "RouterID2",
"TimeStamp": array of timestamps
"transferBytes": array of bytes transferred for each timestamp
"ReceivedBytes": array of bytes received for each timestamp
}
]
#Bergi I want to make an object for each router with there historical data contained with in the object. Right know I have an object for every time entry. (I think)
#Rick Good call, I will be and will probably ask that question later:)
You can really just create the objects on the fly. It's not going to be any faster to hardcode a set of router objects, and it's likely you'll make mistakes by handwriting.
Take a look at this : http://jsfiddle.net/aSbm6/
I would start with turning the json into a php variable, so that you can operate on it more easily. It looks like your Json is one big array of objects, so it would look like this:
$routerArray = json_decode($yourJsonString);
Then you can iterate and get your data:
$newRouterObjectsArray = array();
foreach($routerArray as $routerObject) {
if (empty($newRouterObjectsArray[$Router])) {
// instantiate new router here:
$newRouterObjectsArray[$Router] = new Router([params]);
}
// any other logic, assuming that the router does exist
}
If you're doing this directly in javascript, it would look like:
var routerArray = JSON.parse([yourJsonString]);
var newRouterObjects = {};
for (routerEntry in routerArray) {
if ('undefined' == typeof newRouterObjects[routerEntry->Router]) {
//if this router doesn't exist yet, create it
newRouterObjects[routerEntry->Router] = new Router([params]);
}
// update totals, etc.
}
JSON.parse--or your library's equivalent--if given your JSON file, will return an array of objects, so you don't need to create objects.
If we call data the JSON string in your example then:
var routers = JSON.parse(data);
routers[0].Router === "DWG-350"; // true
routers[1].TimeStamp === "2012/01/01 06:05:00"; // true
routers[0].Router === routers[1].Router; // true
routers[0].TimeStamp === routers[1].TimeStamp; // false
If you need to do logic or filtering then you can use all the objects in routers as Javascript objects, because they are.
It's unclear exactly what you're trying to do, though.
I think this is the logic that you want:
var routers = JSON.parse(data), // or jQuery.parseJSON()
aggregate = {};
for (var i = 0, max = routers.length;
i < max;
i++) {
var router = routers[i];
if (typeof aggregate[routers[i].Router] === 'undefined') {
aggregate[router['Router']] = {"TimeStamp": [],
"ReceivedBytes": []}
"TransferredBytes": []};
}
aggregate[router['Router']]["TimeStamp"]
.push(router['TimeStamp']);
aggregate[router['Router']]["ReceivedBytes"]
.push(router['ReceivedBytes']);
aggregate[router['Router']]["TransferredBytes"]
.push(router['TransferredBytes']);
}