How can I reference this data in this JSON file? - javascript

I am using d3.js's "d3.json(); function to reach out and fetch some data from a REST API.
The data comes back as this:
{
"offset" : 0,
"rows": [
{ "_id":
{ "$oid" : "1234567" },
"mockupData" : [ {
"Analysis" : "Test",
"Description" : "The Test indicates...",
"Data" : [
{ "Category" : "A",
"Statistic" : 0.15,
"Value" : 0.95 },
{ "Category" : "B",
"Statistic" : 0.65,
"Value" : 0.85 },
] } ] }
],
"total_rows" : 1 ,
"query" : {} ,
"millis" : 0
}
I am having an extremely difficult time drilling down in to the json to get what I want.
I'm attempting to set it up like this:
function generateChart(){
var chart;
var Category = [{key:"Stuff", values:[]}];
d3.json('http://url_that_returns_json/', function(error,data{
for(var key in data._SOMETHING_){
switch(key){
case "A":
Category[0] ["values"].push({"label":"Statistic","value""data.Category[key]});
... // same for B
})
// more graph logic
I appear to be missing some entire fragment of knowledge on this. Guidance? Help?
Thanks in advance.

Here is a fiddle I have implemented : https://jsfiddle.net/thatOneGuy/486mwb86/1/
First off, I set the data as a variable so I can use it later. So :
var data = {
"offset": 0,
"rows": [{
"_id": {
"$oid": "1234567"
}, ... //and so on
This is exactly the same as you using :
d3.json('http://url_that_returns_json/', function(error,data{
Both data variables are the same.
Then I got to the point you wanted to check, i.e the categories in the data attribute, like so :
var thisDataSet = data.rows[0].mockupData[0].Data;
As this is an array and not an object, I used a for loop to loop through :
for (var i = 0; i < thisDataSet.length; i++) {
And, in my opinion, you didn't need a switch statement as it looks like you just wanted to populate Category.values with the different categories. So I just pushed the current value of the category in the dataset to this Category.values :
Category[0]["values"].push({
"label": "Statistic",
"value": thisDataSet[i].Category //push category here
});
And that's it. Check the console log for output. Should work fine. Full function :
function generateChart() {
var chart;
var Category = [{
key: "Stuff",
values: []
}];
console.log(data.rows[0].mockupData[0].Data)
var thisDataSet = data.rows[0].mockupData[0].Data;
for (var i = 0; i < thisDataSet.length; i++) {
//for (var key in data.rows[0].mockupData[0].Data) {
console.log(thisDataSet[i])
Category[0]["values"].push({
"label": "Statistic",
"value": thisDataSet[i].Category
});
}
console.log(Category)
}

Related

How to remove empty object in array?

I am trying to remove the empty object {} from the below structure.
data = [{
"total" : "value",
"status" : "statusVal",
"recs" : [{
"total" : "value",
"region" : "name",
"recs" : [{},{
"recs" : [{
"recs" : [{
"value" : "a",
"label" : "fn"
}]
}]
}]
}]
}]
This is my JavaScript code where I process the data and trying to remove the empty object from the result.
var result = json.parse(data);
for(var i=0;i<result.length;i++){
if(result[i].hasOwnProperty("recs")){
var fset = result[i].recs;
for(var j=0;j<fset.length;j++){
if(fset[j].recs === undefined || fset[j].recs === null){
delete fset[j].recs;
}
if(fset[j].hasOwnProperty("recs")){
var sset = fset[i].recs;
for(var k=0;k<sset.length;k++){
var tset = sset[i].recs;
if(sset[k].hasOwnProperty("recs")){
for(var z=0;z<tset.length;z++){
if(tset[z].hasOwnProperty("recs")){
// logic to push
}
}
}
}
}
}
}
}
I tried checking null and undefined and also with property check bool as false. Since the empty {} is always returning length as 1, that is also ruled out. I am stuck here on processing the removal of empty object.
Above code is removing the entire recs node. Can you help me find what I am missing?
Check the length of the Object.keys() to see if object is empty or not.
Object.keys(fset[j].recs).length === 0
You can't iterate all the dynamic levels of array manually, so better to write the function which has recursive function call.
var data = [{
"total": "value",
"status": "statusVal",
"recs": [{
"total": "value",
"region": "name",
"recs": [{}, {
"recs": [{
"recs": [{
"value": "a",
"label": "fn"
}]
}]
}]
}]
}]
function removeEmpty(ary) {
ary.forEach((item, index) => {
if (Object.keys(item).length === 0) { ary.splice(index, 1); }
else if (item.recs && item.recs.length > 0)
removeEmpty(item.recs)
});
}
removeEmpty(data)
console.log(data)

How to display all fields of a nested json in table format using Bootstrap

I want to write a utility which connects to a REST api downloads data in JSON format and then paints the data as nested tables using Bootstrap.
JSON Data -
[
{
"id" : "Id1",
"name" : "Name1",
"orders" : [{"orderId" : "o1", "size" : 34}, {"orderId" : "o2", "size" : 3}]
},
{
"id" : "Id2",
"name" : "Name2",
"orders" : [
{"orderId" : "o3", "size" : 5, "addresses" : [{"addressId" : "a1", "phone" : "1235"}, {"addressId" : "a2", "phone" : 555}]},
{"orderId" : "o4", "size" : 5, "addresses" : [{"addressId" : "a3", "phone" : "1235"}]}
]
}
]
I looked at the sub-table feature of Bootstrap, however it seems that it would need lot of custom code to get this working. Is there a better way to bind the json to table in a generic way?
Edit
After spending some time I was able to achieve this -
As you can see, I could get one level of nesting, however i just need to go one level deep. Any suggestions?
<script>
var $table = $('#table')
function buildTable($el, jsonData) {
var i; var j; var row
var columns = []
var data = []
if(!Array.isArray(jsonData) && jsonData.length == 0) {
return;
}
Object.keys(jsonData[0]).forEach( (k) => {
columns.push({
field: k,
title: k,
sortable: true
})
})
for(var j = 0; j < jsonData.length; j++) {
row = {}
Object.keys(jsonData[j]).forEach( (k) => {
row[k] = jsonData[j][k]
})
data.push(row)
}
$el.bootstrapTable({
columns: columns,
data: data,
detailFilter: function (index, row) {
console.log("detail filter " + Object.values(row))
for(var k in row) {
if(Array.isArray(row[k])){
return true;
}
}
return false;
},
onExpandRow: function (index, row, $detail) {
console.log("expand row keys " + Object.keys(row))
console.log("expand row vals " + Object.values(row))
var newRow = {};
for(var k in row) {
if(Array.isArray(row[k])){
alert('found ' + row[k])
newRow = row[k]
break
}
}
buildTable($detail.html('<table></table>').find('table'), newRow)
}
})
};
var mydata =
[
{
"id": 0,
"name": "test0",
"price": "$0",
"orders" :
[
{
"name" : "ABC",
"size" : 25,
"someList": [{"a":1, "b":2}, {"a":3, "b":4}]
},
{
"name" : "XYZ",
"size" : 50
}
]
}
/* {
"id": 1,
"name": "test1",
"price": "$1"
},
{
"id": 2,
"name": "test2",
"price": "$2",
"orders" : [{"name" : "def", "size": 45}]
}*/
];
$(function() {
buildTable($table, mydata)
})

Filter object by array of ids

I have a list of objects. On each object I have an array.
Example:
"-KpvPH2_SDssxZ573OvM" : {
"date" : "2017-07-25T20:21:13.572Z",
"description" : "Test",
"id" : [ {
0: "0a477fed-8944-9f5d-56fd-c95fe7663a07",
1: "0a477fed-8944-9f5d-56fd-c95fe7663a08"
} ]
},
"-KpvPLSfotrZiBDeVOxU" : {
"date" : "2017-07-25T20:21:33.159Z",
"description" : "Test 2",
"id" : [ {
0: "6e79eadd-21b5-91cc-4b71-7ac1a42278b1"
} ]
}
How do I search for an object using the ID array as a parameter?
When I need to filter only one array I use filter and everything works ok.
var result = $.grep(items, function(e){ return e.id == id; });
But in this case I believe it does not work.
Thanks
Since the ID's are a little deeper in the object, and they are part of an object, I think a better approach (as compared to $.grep) would be a custom filter. Here I have assumed you want exact comparison while filtering, based on your question. But you could easily have partial comparison with indexOf as well.
var data = {
"-KpvPH2_SDssxZ573OvM": {
"date": "2017-07-25T20:21:13.572Z",
"description": "Test",
"id": [{
0: "0a477fed-8944-9f5d-56fd-c95fe7663a07",
1: "0a477fed-8944-9f5d-56fd-c95fe7663a08"
}]
},
"-KpvPLSfotrZiBDeVOxU": {
"date": "2017-07-25T20:21:33.159Z",
"description": "Test 2",
"id": [{
0: "6e79eadd-21b5-91cc-4b71-7ac1a42278b1"
}]
}
};
//console.log(data);
var inputID = "0a477fed-8944-9f5d-56fd-c95fe7663a08";
var filteredData = [];
for (var prop in data) {
if(data.hasOwnProperty(prop)) {
var item = data[prop];
var itemIDs = item.id[0];
for(var id in itemIDs) {
if (itemIDs[id] == inputID) {
filteredData.push(item);
}
}
}
}
console.log(filteredData);

Get specific object by id from array of objects in AngularJS

I have a JSON file containing some data I d like to access on my AngularJS website. Now what I want is to get only one object from the array. So I d like for example Item with id 1.
The data looks like this:
{ "results": [
{
"id": 1,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
] }
I'd like to load the data with AngularJS $http functionality like this:
$http.get("data/SampleData.json");
which is working. But how can I now get a specific data object (by id) from the array I get from $http.get ?
Using ES6 solution
For those still reading this answer, if you are using ES6 the find method was added in arrays. So assuming the same collection, the solution'd be:
const foo = { "results": [
{
"id": 12,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
] };
foo.results.find(item => item.id === 2)
I'd totally go for this solution now, as is less tied to angular or any other framework. Pure Javascript.
Angular solution (old solution)
I aimed to solve this problem by doing the following:
$filter('filter')(foo.results, {id: 1})[0];
A use case example:
app.controller('FooCtrl', ['$filter', function($filter) {
var foo = { "results": [
{
"id": 12,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
] };
// We filter the array by id, the result is an array
// so we select the element 0
single_object = $filter('filter')(foo.results, function (d) {return d.id === 2;})[0];
// If you want to see the result, just check the log
console.log(single_object);
}]);
Plunker: http://plnkr.co/edit/5E7FYqNNqDuqFBlyDqRh?p=preview
For anyone looking at this old post, this is the easiest way to do it currently. It only requires an AngularJS $filter. Its like Willemoes answer, but shorter and easier to understand.
{
"results": [
{
"id": 1,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
]
}
var object_by_id = $filter('filter')(foo.results, {id: 2 })[0];
// Returns { id: 2, name: "Beispiel" }
WARNING
As #mpgn says, this doesn't work properly. This will catch more results. Example: when you search 3 this will catch 23 too
personally i use underscore for this kind of stuff... so
a = _.find(results,function(rw){ return rw.id == 2 });
then "a" would be the row that you wanted of your array where the id was equal to 2
I just want to add something to Willemoes answer.
The same code written directly inside the HTML will look like this:
{{(FooController.results | filter : {id: 1})[0].name }}
Assuming that "results" is a variable of your FooController and you want to display the "name" property of the filtered item.
You can use ng-repeat and pick data only if data matches what you are looking for using ng-show
for example:
<div ng-repeat="data in res.results" ng-show="data.id==1">
{{data.name}}
</div>
You can just loop over your array:
var doc = { /* your json */ };
function getById(arr, id) {
for (var d = 0, len = arr.length; d < len; d += 1) {
if (arr[d].id === id) {
return arr[d];
}
}
}
var doc_id_2 = getById(doc.results, 2);
If you don't want to write this messy loops, you can consider using underscore.js or Lo-Dash (example in the latter):
var doc_id_2 = _.filter(doc.results, {id: 2})[0]
If you want the list of items like city on the basis of state id then use
var state_Id = 5;
var items = ($filter('filter')(citylist, {stateId: state_Id }));
Unfortunately (unless I'm mistaken), I think you need to iterate over the results object.
for(var i = 0; i < results.length; i += 1){
var result = results[i];
if(result.id === id){
return result;
}
}
At least this way it will break out of the iteration as soon as it finds the correct matching id.
Why complicate the situation? this is simple write some function like this:
function findBySpecField(data, reqField, value, resField) {
var container = data;
for (var i = 0; i < container.length; i++) {
if (container[i][reqField] == value) {
return(container[i][resField]);
}
}
return '';
}
Use Case:
var data=[{
"id": 502100,
"name": "Bərdə filialı"
},
{
"id": 502122
"name": "10 saylı filialı"
},
{
"id": 503176
"name": "5 sayli filialı"
}]
console.log('Result is '+findBySpecField(data,'id','502100','name'));
output:
Result is Bərdə filialı
The only way to do this is to iterate over the array. Obviously if you are sure that the results are ordered by id you can do a binary search
$scope.olkes = [{'id':11, 'name':'---Zəhmət olmasa seçim edin---'},
{'id':15, 'name':'Türkyə'},
{'id':45, 'name':'Azərbaycan'},
{'id':60, 'name':'Rusya'},
{'id':64, 'name':'Gürcüstan'},
{'id':65, 'name':'Qazaxıstan'}];
<span>{{(olkes | filter: {id:45})[0].name}}</span>
output: Azərbaycan
If you can, design your JSON data structure by making use of the array indexes as IDs. You can even "normalize" your JSON arrays as long as you've no problem making use of the array indexes as "primary key" and "foreign key", something like RDBMS. As such, in future, you can even do something like this:
function getParentById(childID) {
var parentObject = parentArray[childArray[childID].parentID];
return parentObject;
}
This is the solution "By Design". For your case, simply:
var nameToFind = results[idToQuery - 1].name;
Of course, if your ID format is something like "XX-0001" of which its array index is 0, then you can either do some string manipulation to map the ID; or else nothing can be done about that except through the iteration approach.
I know I am too late to answer but it's always better to show up rather than not showing up at all :). ES6 way to get it:
$http.get("data/SampleData.json").then(response => {
let id = 'xyz';
let item = response.data.results.find(result => result.id === id);
console.log(item); //your desired item
});
The simple way to get (one) element from array by id:
The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.
function isBigEnough(element) {
return element >= 15;
}
var integers = [12, 5, 8, 130, 160, 44];
integers.find(isBigEnough); // 130 only one element - first
you don't need to use filter() and catch first element xx.filter()[0] like in comments above
The same for objects in array
var foo = {
"results" : [{
"id" : 1,
"name" : "Test"
}, {
"id" : 2,
"name" : "Beispiel"
}, {
"id" : 3,
"name" : "Sample"
}
]};
var secondElement = foo.results.find(function(item){
return item.id == 2;
});
var json = JSON.stringify(secondElement);
console.log(json);
Of course if you have multiple id then use filter() method to get all objects.
Cheers
function isBigEnough(element) {
return element >= 15;
}
var integers = [12, 5, 8, 130, 160, 44];
integers.find(isBigEnough); // 130 only one element - first
var foo = {
"results" : [{
"id" : 1,
"name" : "Test"
}, {
"id" : 2,
"name" : "Beispiel"
}, {
"id" : 3,
"name" : "Sample"
}
]};
var secondElement = foo.results.find(function(item){
return item.id == 2;
});
var json = JSON.stringify(secondElement);
console.log(json);
projectDetailsController.controller('ProjectDetailsCtrl', function ($scope, $routeParams, $http) {
$http.get('data/projects.json').success(function(data) {
$scope.projects = data;
console.log(data);
for(var i = 0; i < data.length; i++) {
$scope.project = data[i];
if($scope.project.name === $routeParams.projectName) {
console.log('project-details',$scope.project);
return $scope.project;
}
}
});
});
Not sure if it's really good, but this was helpful for me..
I needed to use $scope to make it work properly.
use $timeout and run a function to search in "results" array
app.controller("Search", function ($scope, $timeout) {
var foo = { "results": [
{
"id": 12,
"name": "Test"
},
{
"id": 2,
"name": "Beispiel"
},
{
"id": 3,
"name": "Sample"
}
] };
$timeout(function () {
for (var i = 0; i < foo.results.length; i++) {
if (foo.results[i].id=== 2) {
$scope.name = foo.results[i].name;
}
}
}, 10);
});
I would iterate over the results array using an angularjs filter like this:
var foundResultObject = getObjectFromResultsList(results, 1);
function getObjectFromResultsList(results, resultIdToRetrieve) {
return $filter('filter')(results, { id: resultIdToRetrieve }, true)[0];
}

How to access specific elements in a Json array?

I have a Json array which has the elements below:
"adjacencies", "data", "id", "name".
In some elements, "adjacencies" does not exist.
This is an example:
var JsonArray = [
{
"id" : "id1",
"name" : "name1",
"data" : {
"$type" : "circle",
"$color" : "#AEC43B"
}
}, //Without "adjacencies"
{
"id" : "id2",
"name" : "name2",
"data" : {
"$type" : "circle",
"$color" : "#AEC43B"
}
}, //Without "adjacencies"
{
"adjacencies": [
{
"nodeTo": "id1",
"nodeFrom": "id3",
"data": {
"$color": "#416D9C"
}
}
],
"id" : "id3",
"name" : "name3",
"data" : {
"$type" : "circle",
"$color" : "#AEC43B"
}
} //With "adjacencies"
];
The first and the second elements doesn't contain "adjacencies", but the third element does.
In the loop for (i = 0; i < JsonArray.length; i++) how do I access the third element?
Is there a .contain property for example?
Thanks in advance:)
One way to do it is by checking if the value is of type undefined:
for (i = 0; i < JsonArray.length; i++) {
var item = JsonArray[i];
if (typeof item.adjacencies !== "undefined") {
// item has adjacencies property
}
}
As an aside: this is not a JSON array -- it's a Javascript array. There are no JSON objects, no JSON arrays, no JSON nothing. The only JSON-y thing that exists is plain JSON, which is a serialization format.
use hasOwnProperty
So you can do this
for (i = 0; i < JsonArray.length; i++){
if( JsonArray[i].hasOwnProperty('adjacencies') ){
//Do something here
}
}

Categories

Resources