filter data from result of json call
I am trying to do pre-processing JSON data before feed it to the dataTables. the reason is I need to separate the source data into 3 datatables. i can do it in the server-side in java but that approach is undesirable.
Please don't ask why, it is just due to load balancing calculation.
type: "GET",
dataType: 'json',
contentType: 'application/json',
success: function (data) {
console.log(data);
var table = $('#tbl1');
var tableUsul = $('#tbl1Terima');
var tableTolak = $('#tbl2Tolak');
table.DataTable({
"data": data.object, // i want to maipulate this
"processing": true,
"destroy": true,
"pagingType": "numbers",
"columns": [
{"data": null, "class": "rowCenter"},
{"data": "0"},
{"data": "1"},
{"data": "2"}
........
console.log(data.object) result
[
[1,"myname1","1000"],
[0,"myname2","0"],
[1,"myname5","12121"],
[1,"myname2","23455"]
]
i want to filter data.object. so in the database, the 1st column consists of 1 and 0, I want to show only 1 or only 0.
i was trying to use data.filter(function(){}) but the js does not recognize the function filter.
you can try something like below.
var data = [
[1,"myname1","1000"],
[0,"myname2","0"],
[1,"myname5","12121"],
[1,"myname2","23455"]
];
var newArray = [];
for (i = 0; i < data.length; i++) {
var element = data[i];
if(element[0] == 1)
{
newArray.push(element);
}
}
console.log(newArray)
You can try the following:
let data = [[1,"myname1","1000"],[0,"myname2","0"],[1,"myname5","12121"],[1,"myname2","23455"]];
function group2DArrayDataByIndex(dataArr, groupByIndex) {
let groupedData = dataArr.reduce(function (acc, arr) {
if (Array.isArray(arr) && (arr[groupByIndex] !== undefined || arr[groupByIndex] !== null)) {
let key = arr[groupByIndex];
if (Array.isArray(acc[key])) {
acc[key].push(arr);
} else {
acc[key] = [arr];
}
}
return acc;
}, {});
return groupedData;
}
let groupByIndex = 0;
let groupedData = group2DArrayDataByIndex(data, groupByIndex);
console.log(groupedData);
console.log(groupedData[0]); //access data with only 0
console.log(groupedData[1]); //access data with only 1
What it does: This code groups the data (Array of Arrays) based on the supplied index to be used to group data. All the grouped data is stored in an object such that you can access any data without the need to group/filter again.
Related
How do I create the data array from my second api call result into the format I want?
I have a code like this
var github = require('octonode');
var client = github.client();
var userName = "octocat";
var repoName = "";
var branchName = "";
var data = [];
var branches = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
//==============================
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
bodyChild.forEach(function(objChild) {
branchName = objChild.name;
});
});
});
});
I have received repoName and branchName data as well.
I want my data format like
How to use
data.push({
name: repoName,
branches: 'branchName loooping here for every repoName'
});
so branches repetition data can be contained in my branches tag
Thank you
I guess you can do something like this:
var data = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
let elem = {"name": repoName, "branches": []}; //create json object for each repo
bodyChild.forEach(function(objChild) {
elem.branches.push(objChild.name); //push all branchs to that elem
});
data.push(elem); // add the elem to the data array
});
});
});
So in this case data is an object, that has a property name which is string, and another property branches which is array. If you want to push data to the property branches you can just call the push() function on it.
Please check the example below:
let data = {
name: "repoName",
branches: [
{
name: "foo"
}
]
}
data.branches.push(
{
name: "bar"
}
);
console.log(data);
I am trying to send array to the server side by stringyfing it but after the operation the result is empty []. There is my code:
let calculatePriceOfMultipleFields = (model, field, select, computable) => {
if(computable.length === 0){
return false
}
let priceArray = fillPriceArray(model, computable)
console.log(priceArray)
console.log(JSON.stringify(priceArray))
let ajaxData = {
id: select.value,
model: model,
field: field,
priceArray: priceArray
}
$.ajax({
url: "/erp/currencyhandler/multiple-currency-handler/get-price-by-currency",
data: ajaxData,
success: function ( data ) {
console.log(data)
return false
}
})
}
let fillPriceArray = (model, computable) => {
let price = []
computable.forEach((name) => {
let id = model.toLowerCase()+"-"+name
let input = document.getElementById(id)
price[id] = input.value
})
return price
}
What I get from the console.log is:
[crmorder-amount: "6.22", crmorder-delivery_price: "5", crmorder-discount_percentage: "15", crmorder-total_amount: "10.29"]
On the first one where the array is filled up and the second one is simply [].
What is wrong with my stringyfing and where is my mistake ? Thank you!
I am making a bar chart component which I import in my app.js. My JSON data contains cricket match information i.e season and runs (i.e runs scored in that season). On Y-axis the height of bar will be sum of all the runs in particular season and on X-axis the labels would be the season.
For below JSON example:
season 2008 -> runs = 100+200=300
season 2009 -> runs = 300
season 2010 -> runs = 1100
season 2011 -> runs = 100
JSON data:
[
{
"season":2008,
"runs":100
},
{
"season":2008,
"runs":200
},
{
"season":2009,
"runs":300
},
{
"season":2010,
"runs":600
},
{
"season":2010,
"runs":500
},
{
"season":2011,
"runs":100
}
]
Chart component:
import React, { Component } from 'react';
import ChartistGraph from 'react-chartist';
const ChartData = {
//labels are the season
labels: [ ],
series: [
// runs will be injected here
],
distributeSeries: true
}
const options = {
width: 720,
height: 400
}
class Chart extends Component {
render(){
return(
<div>
<ChartistGraph data={ChartData} type={'Bar'} options={options}/>
</div>
)}
}
export default Chart;
Instead of hardcoding the data from JSON data how can I inject season as labels and runs as series. I tried using for loop but I was not able to get sum of runs for a particular season. eg: for season 2008 it should be 100+200=300 i.e label=2008 and series element corresponding to it will be 300.
Note: For given JSON data series will be :
series:[300, 300, 1100, 100]
using array reduce to combine the seasons, and another reduce to create the two arrays
var json = `[
{
"season":2008,
"runs":100
},
{
"season":2008,
"runs":200
},
{
"season":2009,
"runs":300
},
{
"season":2010,
"runs":600
},
{
"season":2010,
"runs":500
},
{
"season":2011,
"runs":100
}
]`
var data = Object.entries(JSON.parse(json).reduce((acc, {season, runs}) => (acc[season] = (acc[season] || 0) + runs, acc), {}))
.reduce((acc, [labels, series]) => (acc.labels.push(labels), acc.series.push(series), acc),{labels: [], series:[]})
console.log(data)
Broken down in ES5, step by step
var json = `[
{
"season":2008,
"runs":100
},
{
"season":2008,
"runs":200
},
{
"season":2009,
"runs":300
},
{
"season":2010,
"runs":600
},
{
"season":2010,
"runs":500
},
{
"season":2011,
"runs":100
}
]`
var data = JSON.parse(json); // because JSON is a string representation of an javascript object
var data1 = data.reduce(function (acc, item) {
var season = item.season,
runs = item.runs;
acc[season] = acc[season] || 0; // add a season as a key
acc[season] += runs; // add runs
return acc;
}, {});
console.log(data1);
var data2 = Object.entries(data1); // make an array of [[label, runs],[label, runs]...]
console.log(data2);
var data3 = data2.reduce(function (acc, item) { // each item is an array of [year, total runs]
var labels = item[0],
series = item[1];
acc.labels.push(labels);
acc.series.push(series);
return acc;
}, { labels: [], series: [] }); // initialise the return object
console.log(data3);
Create new array, loop through all elements of current array, parse them by their key and see if value is unique in our new array, if it's not add to that, if it is create new element.
function fillGraph(data){
var newArray = []; //creating new, empty array
for(var i = 0; i < data.length; i++){ //going through all elements of data array
if(newArray.hasOwnProperty(data[i]["season"]){ //if it already has that season
newArray["season"] += data[i]["runs"]; //add runs to the current season
}else{
newArray.push({data[i]["season"] : data[i]["runs"]}); //if not create new object with key name as a season name and assign runs
}
}
for(var i in newArray) { //go through our new array
chartData.labels.push(i); //push key name of current array element into graph labels property
chartData.series.push(newArray[i]); //push value of current array element into graph series property
});
}
Sharing my take on the task
<script>
// in the url variable I use a link to my JSON, so might try you by
// firstly uploading your JSON at myjson.com
let url = 'https://api.myjson.com/bins/8x9l7';
fetch(url).then(res => res.json()).then((out) => {
// here you might try console.log(out); to check the correctness of
// displaying your JSON imported via URL
convertJsonToData(out);
}).catch(err => { throw err });
let data = {
labels: [],
series: [[]]
};
function convertJsonToData(jsonData) {
for (let x in jsonData) {
data.labels.push(jsonData[x].transactTime); //transactTime and walletBalance are keys in my JSON, you will have yours
data.series[0].push(jsonData[x].walletBalance);
};
// here you might try console.log(data); to check the correctness of
// data display taken from JSON and modified to use in chart
return data;
};
let options = {
showPoint: false,
lineSmooth: true,
fullWidth: true,
height: 700,
showArea:true,
};
new Chartist.Line('.ct-chart', data, options);
</script>
I am trying to access keys and values in a JSON response to fill an array. This array is currently blank and is used for chart.js. The API: https://api.coindesk.com/v1/bpi/historical/close.json has keys and values that are changing every 24 hours, i.e.:
{"bpi":
{"2017-10-06":4370.245,
"2017-10-07":4437.0338,
}
}
The array 'data' needs to be filled inside the component.ts file, and not in a template or .html file
chartData = [
{ data: [], label: 'Bitcoin' },
];
To clarify, I am trying to fill the array 'data' with values such as '4370.245' which are coming from an http.get request from the above url.
Try this
chartData = [
{ data: [], label: 'Bitcoin' },
];
let arrayData = chartData[0].data;//this will return you data inside chartData
Edited as per coomment
var outputData = []
var keysArray = Object.keys(tmpObj.bpi)
for (var key in tmpObj.bpi) {
if (tmpObj.bpi.hasOwnProperty(key )) {
outputData.push(tmpObj.bpi[key])
}
}
console.log(outputData);
var tmpObj = {"bpi":
{"2017-10-06":4370.245,
"2017-10-07":4437.0338,
}
};
var outputData = []
var keysArray = Object.keys(tmpObj.bpi)
for (var key in tmpObj.bpi) {
if (tmpObj.bpi.hasOwnProperty(key )) {
outputData.push(tmpObj.bpi[key])
}
}
console.log(outputData);
I have an array with 3 Objects, however the second Object does not have an array inside the 'Data' Object.
I need to do an ng-repeat for each 'Artist' in the correct order, however the second object is causing issues. How would I combine each Object together?
In my Factory, I set up a call to receive three response from three different API. I set a promise for each one so they come in a the exact order I call them.
FACTORY
.factory('timeline', function($http, $q) {
var promise1 = $http({
method: "GET",
url: "http://api.example.com/last/3/?limit=3"
});
var promise2 = $http({
method: "GET",
url: "http://api.example.com/current/3/"
});
var promise3 = $http({
method: "GET",
url: "http://api.example.com/next/3/?limit=3"
});
return {
data: $q.all([promise1, promise2, promise3])
}
})
In my controller, I get the response like so.
[
Object
config
data: [Array 3]
-0: Object
artist : 'Artist'
title : 'Title'
-1: Object
-2: Object
,
Object
config
data: Object
artist : 'Artist'
title : 'Title
,
Object
config
data: [Array 3]
-0: Object
artist : 'Artist'
title : 'Title'
-1: Object
-2: Object
]
CONTROLLER
My Attempt to filter using Underscore.
.controller('StationCtrl', function($scope, $stateParams, $http, timeline) {
timeline.data.then(function(musicData) {
var row = [];
for (var i = 0; i < musicData.length; i++) {
var data = _.filter(musicData[i].data, function(x){
row.push(x);
})
}
})
})
My Goal eventually if possible would be to combine everything in order
Object
data: [Array 7]
-0: Object
-1: Object
-2: Object
-3: Object
-4: Object
-5: Object
-6: Object
,
I am still trying to figure out how to work with Objects & Arrays, any help/tips would be great.
This is a simple approach of how you can solve your problem without underscore. You just need to check whether your data is an object or an array.
var arr = [
{ data: [{ artist: 'Artist' }, { artist: 'Artist2' }]},
{ data: { artist: 'Artist3' } },
{ data: [{ artist: 'Artist4' }]}
];
var flattened = [];
arr.forEach(function (el) {
if(Array.isArray(el.data)) {
flattened = flattened.concat(el.data);
} else {
flattened.push(el.data);
}
});
See example on jsbin.
Ideally, I think you should send an array only for 2nd object with its length as 1. If the API is not in your control i.e. 3rd party or anything else then we can look forward to solve the issue in other way.
You could strip out the underscore and just do a nested for:
.controller('StationCtrl', function($scope, $stateParams, $http, timeline) {
timeline.data.then(function(musicData) {
var row = [];
var dataElement;
var i;
var j;
for (i = 0; i < musicData.length; i++) {
dataElement = musicData[i].data;
if(typeof dataElement === 'object') {
row.push(dataElement)
} else if(typeof dataElement === 'array') {
for(j = 0; j < dataElement.length; j++) {
row.push(dataElement[j]);
}
}
}
})
})