I have 2 problems with this code, 1st one is that for the user Edgar Francisco Williams Britez is showing the wrong values for monday, wednesday and friday like this
Mon Tue Wed Thu Fri Sat Sun
10 0 0
It should display like this
Mon Tue Wed Thu Fri Sat Sun
0
values for user FREDY RAMON BAEZ OCAMPOS are displaying correctly but then it should sum the total of each user per day but is not doing that correctly.
The Total it displays like this
Mon Tue Wed Thu Fri Sat Sun
10 0 0
expected result:
Mon Tue Wed Thu Fri Sat Sun
10 2 0
So that at the end the table it's supposed to look like this:
User Mon Tue Wed Thu Fri Sat Sun
FREDY RAMON BAEZ OCAMPOS 10 2 0
Edgar Francisco Williams Britez 0
Totals 10 2 0
I don't know what I'm doing wrong to be honest, if anyone can give me some help
const myObj = {
"data": {
"1660": {
"3": {
"1": {
"RC": 10,
"time": "Entrada: 07:40:26\nSalida: 17:18:45\n",
"distance": "Entrada: 45 mts\nSalida: 41 mts\n",
"RCNP": 10,
"RCP": 0,
"status": "5"
},
"3": {
"RC": 2,
"time": "Entrada: 07:46:17\n",
"distance": "Entrada: 44 mts\n",
"RCNP": 1,
"RCP": 1,
"status": "1"
},
"5": {
"RC": 0,
"time": "",
"distance": "",
"RCNP": 0,
"RCP": 0,
"status": "0"
}
},
"total": {
"1": {
"RC": 10,
"time": "",
"distance": "",
"RCNP": 10,
"RCP": 0
},
"3": {
"RC": 2,
"time": "",
"distance": "",
"RCNP": 1,
"RCP": 1
},
"5": {
"RC": 0,
"time": "",
"distance": "",
"RCNP": 0,
"RCP": 0
}
}
},
"1941": {
"3": {
"3": {
"RC": 0,
"time": "Entrada: 16:19:15\nSalida: 16:19:17\n",
"distance": "Entrada: 6602879 mts\nSalida: 6602879 mts\n",
"RCNP": 0,
"RCP": 0,
"status": "5"
}
},
"total": {
"3": {
"RC": 0,
"time": "",
"distance": "",
"RCNP": 0,
"RCP": 0
}
}
}
},
"error": false,
"userData": {
"1660": "FREDY RAMON BAEZ OCAMPOS",
"1941": "Edgar Francisco Williams Britez"
}
}
loadResumeForAuditor(myObj);
function loadResumeForAuditor(resultMap) {
let tableResume = document.getElementById("tableResume"); //id de la tabla
let trResume = document.getElementById('trResume'); //id del tr
let trCloned;
let footer = document.getElementById("tfootContainer"); //id tfoot totales
var eventTypeSelect = jQuery('input[name="customRadio"]:checked').attr("id");
//console.log(resultMap.data);
for (const [userId, weekValue] of Object.entries(resultMap.data)) {
trCloned = trResume.cloneNode(true);
document.getElementsByClassName("group-auditor")[0].innerText = resultMap.userData[userId];
document.getElementsByClassName('tBodyContainer')[0].appendChild(trCloned);
for (const [key, summaryData] of Object.entries(weekValue)) {
if (key == "total") {
for (const [dayOfWeek, totalValue] of Object.entries(summaryData)) {
document.getElementsByClassName("total-day-" + dayOfWeek)[0].innerText = totalValue[eventTypeSelect];
//console.log(totalValue[eventTypeSelect]);
}
} else {
for (const [dayOfWeek, resumeValue] of Object.entries(summaryData)) {
let tdColor = jQuery("#legendTable td[id='" + resumeValue["status"] + "']").attr("class");
document.getElementsByClassName("resume-day-" + dayOfWeek)[0].innerText = resumeValue[eventTypeSelect];
//console.log(resumeValue[eventTypeSelect]);
jQuery(document.getElementsByClassName("resume-day-" + dayOfWeek)[0]).parent('td').attr('class', tdColor);
document.getElementsByClassName('tBodyContainer')[0].appendChild(trCloned);
}
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="border p-2 rounded">
<div class="custom-control custom-radio">
<input type="radio" id="RC" name="customRadio" class="custom-control-input" checked="">
<label class="custom-control-label" for="RC">Cantidad de Romaneos</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" id="distance" name="customRadio" class="custom-control-input">
<label class="custom-control-label" for="distance">Distancia Entrada / Salida</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" id="time" name="customRadio" class="custom-control-input">
<label class="custom-control-label" for="time">Horario Entrada / Salida</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" id="RCP" name="customRadio" class="custom-control-input">
<label class="custom-control-label" for="RCP">Fiscalización Presencial</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" id="RCNP" name="customRadio" class="custom-control-input">
<label class="custom-control-label" for="RCNP">Fiscalización No Presencial</label>
</div>
</div>
<table id="tableResume" class="table-sm table-bordered dt-responsive nowrap w-100">
<thead style="width:100%">
<th>User</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
</thead>
<tbody class="tBodyContainer">
<tr id="trResume">
<td><span class="group-auditor"></span></td>
<td class="bg-white"><span class="resume-day-1"></span></td>
<td class="bg-white"><span class="resume-day-2"></span></td>
<td class="bg-white"><span class="resume-day-3"></span></td>
<td class="bg-white"><span class="resume-day-4"></span></td>
<td class="bg-white"><span class="resume-day-5"></span></td>
<td class="bg-white"><span class="resume-day-6"></span></td>
<td class="bg-white"><span class="resume-day-0"></span></td>
</tr>
</tbody>
<tfoot id="tfootContainer">
<th>Totals</th>
<th><span class="total-day-1"></span></th>
<th><span class="total-day-2"></span></th>
<th><span class="total-day-3"></span></th>
<th><span class="total-day-4"></span></th>
<th><span class="total-day-5"></span></th>
<th><span class="total-day-6"></span></th>
<th><span class="total-day-0"></span></th>
</tfoot>
</table>
IMHO What you are doing wrong is mixing the data processing with the presentation. Those are separate concerns
IOW: always write test cases of your data processing first, then worry about presentation later. TDD is an awesome discipline to make sure you get what you want long before your project is put into production.
This is a test that I wrote using your object as base.
The result I got using console.log( report ) was:
[
{
name: 'FREDY RAMON BAEZ OCAMPOS',
days: { '1': 10, '3': 2, '5': 0 }
},
{ name: 'Edgar Francisco Williams Britez', days: { '3': 0 } }
]
and the console.log( totals )
{ '1': 10, '3': 2, '5': 0 }
test code:
class SO_Test extends Test {
test_1(){
const obj = {
"data": {
"1660": {
"3": {
"1": {
"RC": 10,
"time": "Entrada: 07:40:26\nSalida: 17:18:45\n",
"distance": "Entrada: 45 mts\nSalida: 41 mts\n",
"RCNP": 10,
"RCP": 0,
"status": "5"
},
"3": {
"RC": 2,
"time": "Entrada: 07:46:17\n",
"distance": "Entrada: 44 mts\n",
"RCNP": 1,
"RCP": 1,
"status": "1"
},
"5": {
"RC": 0,
"time": "",
"distance": "",
"RCNP": 0,
"RCP": 0,
"status": "0"
}
},
"total": {
"1": {
"RC": 10,
"time": "",
"distance": "",
"RCNP": 10,
"RCP": 0
},
"3": {
"RC": 2,
"time": "",
"distance": "",
"RCNP": 1,
"RCP": 1
},
"5": {
"RC": 0,
"time": "",
"distance": "",
"RCNP": 0,
"RCP": 0
}
}
},
"1941": {
"3": {
"3": {
"RC": 0,
"time": "Entrada: 16:19:15\nSalida: 16:19:17\n",
"distance": "Entrada: 6602879 mts\nSalida: 6602879 mts\n",
"RCNP": 0,
"RCP": 0,
"status": "5"
}
},
"total": {
"3": {
"RC": 0,
"time": "",
"distance": "",
"RCNP": 0,
"RCP": 0
}
}
}
},
"error": false,
"userData": {
"1660": "FREDY RAMON BAEZ OCAMPOS",
"1941": "Edgar Francisco Williams Britez"
}
};
var users = obj.userData;
var id_users = Object.keys( users );
var totals = {};
var report = [];
id_users.forEach( function( id_user ){
let second_level = Object.keys( obj.data[ id_user ] );
let days = {};
second_level.forEach( function( key3 ){
if( key3 === "total" )
return;
var data = obj.data[ id_user ][key3];
var dows = Object.keys( data );
dows.forEach( function( dow ){
if( days[ dow ] === undefined ){
days[ dow ] = 0;
}
if( totals[ dow ] === undefined ){
totals[ dow ] = 0;
}
let num = obj.data[ id_user ][key3][dow]["RC"];
days[ dow ] += num;
totals[ dow ] += num;
})
})
let item_report = {};
item_report.name = users[ id_user ];
item_report.days = days;
report.push( item_report );
})
console.log( report );
console.log( totals );
this.assertTrue( true );
this.done();
}
}
Related
I am trying to polulate a html table using the JSON reponse. I have parsed and use angluar ng-repeat to fill the table. But now I noticed that the JSON reponse type may vary based on the type of user.
JSON response:
[{
"id": 133,
"account": {
"accountNumber": "6335050000000111",
"accountType": "TSys",
"address": {
"companyName": "",
"street1": "",
"street2": "",
"street3": "",
"street4": "",
"country": "GB",
"prepayBalance": 110
}
},
"lastModifiedDate": "Apr 09, 2020",
"lastModifiedBy": "uk#gmail.com"
}, {
"id": 132,
"account": {
"accountNumber": "6335052400000034",
"accountType": "PREPAY",
"address": {
"companyName": "",
"street1": "",
"street2": "",
"street3": "",
"street4": "",
"country": "GB",
"prepayBalance": 130
},
"bankAccount": {
"id": 54390,
"bankAccountName": "ABC Coompany",
"bankAccountNumber": "3245",
"sortCode": "12-34-56",
"address": {
"street1": "Fidelity Bank",
"street2": "10 BANK STREET",
"street3": "LONDON",
"street4": "SW1A 2AA",
"country": "GB"
}
}
},
"lastModifiedDate": "Apr 09, 2020",
"lastModifiedBy": "ukcase#mailinator.com"
}]
As you can see in the response some may or may not receive "bankAccount" as response. I only need to select those which has bank account but at the same time count all the records.
Example:
count(data.account.accountType) //somehow implement the count logic
count(data.account.bankAccount)
// Main logic
$scope.getAllDd = data.account.bankAccount; // get only those records with bankaccount in response
Which I can use for:
<tr ng-repeat="ddAccounts in getAllDd">
<td>{{ddAccounts.account.accountType}}</td>
Declare the unfiltered accounts separate from the filtered ones.
const app = angular.module('AccountApp', []);
const hasBankAccount = (account) => account.account.bankAccount != null;
app.filter('objectValues', () => {
return (obj) => Object.values(obj).join(', ');
});
app.controller('AccountController', function($scope, $http) {
$scope.filters = {
search: ''
};
// Filter here initially...
$scope.accounts = getJson();
$scope.filteredData = $scope.accounts.filter(hasBankAccount);
// Filter even more on search...
$scope.doSearch = function() {
let filterField = document.querySelector('#txt-filter');
let filterText = filterField.value.trim().toLowerCase();
$scope.filteredData = filterText.length === 0
? $scope.accounts.filter(hasBankAccount)
: $scope.filteredData = $scope.accounts
.filter(hasBankAccount)
.filter(account => {
return account.account.accountNumber.toLowerCase().includes(filterText);
});
};
});
function getJson() {
return [{
"id": 133,
"account": {
"accountNumber": "6335050000000111",
"accountType": "TSys",
"address": {
"companyName": "",
"street1": "",
"street2": "",
"street3": "",
"street4": "",
"country": "GB",
"prepayBalance": 110
}
},
"lastModifiedDate": "Apr 09, 2020",
"lastModifiedBy": "uk#gmail.com"
}, {
"id": 132,
"account": {
"accountNumber": "6335052400000034",
"accountType": "PREPAY",
"address": {
"companyName": "",
"street1": "",
"street2": "",
"street3": "",
"street4": "",
"country": "GB",
"prepayBalance": 130
},
"bankAccount": {
"id": 54390,
"bankAccountName": "ABC Company",
"bankAccountNumber": "3245",
"sortCode": "12-34-56",
"address": {
"street1": "Fidelity Bank",
"street2": "10 BANK STREET",
"street3": "LONDON",
"street4": "SW1A 2AA",
"country": "GB"
}
}
},
"lastModifiedDate": "Apr 09, 2020",
"lastModifiedBy": "ukcase#mailinator.com"
}];
}
table, th, td {
border: 1px solid grey;
border-collapse: collapse;
padding: 0.25em;
font-size: 0.9em;
}
table {
width: 100%;
}
.toolbar {
margin-bottom: 1em;
}
.details {
margin-top: 1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="AccountApp">
<div ng-controller="AccountController">
<div class="toolbar">
<input type="button" value="Filter" ng-model="query" ng-model-options="{ debounce: 200 }" ng-click="doSearch()">
<input type="text" id="txt-filter">
</div>
<table>
<thead>
<tr>
<th>#</th>
<th>Acct. No.</th>
<th>Acct. Type</th>
<th>Address</th>
<th>Bank Name</th>
<th>Bank Acct. No.</th>
<th>Bank Address</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="account in filteredData | orderBy : 'account.accountNumber' | filter : filters.search">
<td>{{ $index + 1 }}</td>
<td>{{ account.account.accountNumber }}</td>
<td>{{ account.account.accountType }}</td>
<td>{{ account.account.address.country }}</td>
<td>{{ account.account.bankAccount.bankAccountName }}</td>
<td>{{ account.account.bankAccount.bankAccountNumber }}</td>
<td>{{ account.account.bankAccount.address | objectValues }}</td>
</tr>
</tbody>
</table>
<div class="details">
<strong>No. of Accounts: </strong>
<span ng-bind="filteredData.length"></span> /
<span ng-bind="accounts.length"></span>
</div>
</div>
</div>
have you tried with .filter() methods ? ... something like:
$scope.getAllDd = data.account.filter(xx=> xx. bankAccount)
this.totalRecords = data.account.length;
and then
<tr ng-repeat="ddAccounts in getAllDd">
<td>{{ddAccounts.account.accountType}}</td>
Hope it helps you!!
I have an JSON like this
"result": [{
"channel": "A",
"mkp": "ABC",
"qtd": 6,
"total": 2938.2,
"data": "2019-02-16",
"time": "22:30:40"
}, {
"channel": "C",
"mkp": "DEF",
"qtd": 1545,
"total": 2127229.64,
"data": "2019-02-20",
"time": "17:19:49"
}, {
"channel": "C",
"mkp": "JKL",
"qtd": 976,
"total": 1307328.37,
"data": "2019-02-20",
"time": "17:19:53"
}, {
"channel": "U",
"mkp": "PQR",
"qtd": 77,
"total": 98789.87,
"data": "2019-02-20",
"time": "16:12:31"
}, {
"channel": "U",
"mkp": "STU",
"qtd": 427,
"total": 433206.62,
"data": "2019-02-20",
"time": "17:04:27"
}
]
I need to sum the QTD, the total and return the newest data + time when the channel is the same (eg.: Channel C and U have 2 entries), if it's not so I only will display the values, but I can't figure it out how could I iterate and do these math. Someone could help?
A sample of what I want:
"A": [{
"qtd": 6,
"total": 2938.20,
"dateTime": 2019 - 02 - 16 22: 30: 40 "
}],
"C": [{
"qtd": 2.521,
"total": 3434558.01,
"dateTime": 2019 - 02 - 20 17: 19: 53 "
}],
"U": [{
"qtd": 504,
"total": 531996,
49,
"dateTime": 2019 - 02 - 20 17: 04: 27 "
}]
Currently I separated the values using filter like this:
this.channelA = this.receivedJson.filter(({ channel }) => channel === "A");
You could use reduce method and return one object with object as values.
const data = [{"channel":"A","mkp":"ABC","qtd":6,"total":2938.2,"data":"2019-02-16","time":"22:30:40"},{"channel":"C","mkp":"DEF","qtd":1545,"total":2127229.64,"data":"2019-02-20","time":"17:19:49"},{"channel":"C","mkp":"JKL","qtd":976,"total":1307328.37,"data":"2019-02-20","time":"17:19:53"},{"channel":"U","mkp":"PQR","qtd":77,"total":98789.87,"data":"2019-02-20","time":"16:12:31"},{"channel":"U","mkp":"STU","qtd":427,"total":433206.62,"data":"2019-02-20","time":"17:04:27"}]
const res = data.reduce((r, {channel, qtd, total, data, time}) => {
const dateTime = `${data} ${time}`
if(!r[channel]) r[channel] = {qtd, total, dateTime}
else {
r[channel].total += total
r[channel].qtd += qtd;
r[channel].dateTime = dateTime
}
return r;
}, {})
console.log(res)
You an use reduce to group the values based on channel like this:
const input = [{"channel":"A","mkp":"ABC","qtd":6,"total":2938.2,"data":"2019-02-16","time":"22:30:40"},{"channel":"C","mkp":"DEF","qtd":1545,"total":2127229.64,"data":"2019-02-20","time":"17:19:49"},{"channel":"C","mkp":"JKL","qtd":976,"total":1307328.37,"data":"2019-02-20","time":"17:19:53"},{"channel":"U","mkp":"PQR","qtd":77,"total":98789.87,"data":"2019-02-20","time":"16:12:31"},{"channel":"U","mkp":"STU","qtd":427,"total":433206.62,"data":"2019-02-20","time":"17:04:27"}]
const merged = input.reduce((acc, { channel, qtd, total, data, time }) => {
acc[channel] = acc[channel] || [{ qtd: 0, total: 0, dateTime:'' }];
const group = acc[channel][0];
group.qtd += qtd;
group.total += total;
const dateTime = `${data} ${time}`
if(dateTime > group.dateTime)
group.dateTime = dateTime;
return acc;
}, {})
console.log(merged)
This is my json response i am storing this in
$scope.times = response.data;
My $scope.times json object:
[
{
"id": 1,
"status": true,
"time": "2018-03-05T10:24:15.000Z",
"complaintId": 1
},
{
"id": 2,
"status": true,
"time": null,
"complaintId": 1
},
{
"id": 3,
"status": true,
"time": "2018-03-05T10:53:14.000Z",
"complaintId": 2
},
{
"id": 6,
"status": false,
"time": "2018-03-05T11:58:45.000Z",
"complaintId": 1
},
{
"id": 7,
"status": true,
"time": "2018-03-05T12:11:53.000Z",
"complaintId": 1
},
{
"id": 8,
"status": false,
"time": "2018-03-05T13:23:13.000Z",
"complaintId": 2
},
{
"id": 9,
"status": true,
"time": "2018-03-05T08:17:18.000Z",
"complaintId": 3
},
{
"id": 10,
"status": true,
"time": "2018-03-05T12:32:08.000Z",
"complaintId": 2
}
]
I am displaying this in html using ng-repeat= 'time in times' , but i need to get json object of times with complaintId which located in last, for example there are many complaintId:1 in object.
i need to get only which have complaintId in last.
My expected output in time:
[
{
"id": 7,
"status": true,
"time": "2018-03-05T12:11:53.000Z",
"complaintId": 1
},
{
"id": 9,
"status": true,
"time": "2018-03-05T08:17:18.000Z",
"complaintId": 3
},
{
"id": 10,
"status": true,
"time": "2018-03-05T12:32:08.000Z",
"complaintId": 2
}
]
My ng-repeat looping code:
table
tr
th S.no
th Time
tr(ng-repeat='time in times')
td {{$index + 1 }}
td {{time.status}}
(Don't judge, it's Monday)
Here is the best solution I could find. You can obviously improve it (make it shorter) by using some ES6 magic with .reduce / .filter / .forEach, etc.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="time in times">
<pre>{{time | json}}</pre>
</div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.times = [{"id":1,"status":true,"time":"2018-03-05T10:24:15.000Z","complaintId":1},{"id":2,"status":true,"time":null,"complaintId":1},{"id":3,"status":true,"time":"2018-03-05T10:53:14.000Z","complaintId":2},{"id":6,"status":false,"time":"2018-03-05T11:58:45.000Z","complaintId":1},{"id":7,"status":true,"time":"2018-03-05T12:11:53.000Z","complaintId":1},{"id":8,"status":false,"time":"2018-03-05T13:23:13.000Z","complaintId":2},{"id":9,"status":true,"time":"2018-03-05T08:17:18.000Z","complaintId":3},{"id":10,"status":true,"time":"2018-03-05T12:32:08.000Z","complaintId":2}];
var a = $scope.times;
var b = []; // collect complaintId
for(var i=0;i<a.length;i++){
if(!b.includes(a[i].complaintId)){
b.push(a[i].complaintId);
}
}
var c = []; // collect duplicates per complaintId
for(var i=0;i<b.length;i++){
var temp = []
for(var j=0;j<a.length;j++){
if(b[i] == a[j].complaintId){
temp.push(a[j])
}
}
c.push(temp)
}
// now it's safe to `reduce` the inner arrays (per complaintId)
var d = []; // .forEach .reduce
for(var i=0; i<c.length;i++){
var temp = c[i][0].time;
var temp2 = c[i][0];
for(var j=1; j<c[i].length;j++){
if(c[i][j].time){
if(new Date(c[i][j].time).valueOf() > new Date(temp).valueOf()){
temp = c[i][j].time;
temp2 = c[i][j];
}
}
}
d.push(temp2)
}
$scope.times = d;
});
</script>
</body>
</html>
You can use the Angular Filter module
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.8/angular-filter.min.js"></script>
And then filter out the duplicates using:
ng-repeat="time in times | unique: 'complaintId'"
angular.module('app', ['angular.filter'])
.controller('test', function($scope) {
$scope.items = [
{
"id": 1,
"status": true,
"time": "2018-03-05T10:24:15.000Z",
"complaintId": 1
},
{
"id": 2,
"status": true,
"time": null,
"complaintId": 1
},
{
"id": 3,
"status": true,
"time": "2018-03-05T10:53:14.000Z",
"complaintId": 2
},
{
"id": 6,
"status": false,
"time": "2018-03-05T11:58:45.000Z",
"complaintId": 1
},
{
"id": 7,
"status": true,
"time": "2018-03-05T12:11:53.000Z",
"complaintId": 1
},
{
"id": 8,
"status": false,
"time": "2018-03-05T13:23:13.000Z",
"complaintId": 2
},
{
"id": 9,
"status": true,
"time": "2018-03-05T08:17:18.000Z",
"complaintId": 3
},
{
"id": 10,
"status": true,
"time": "2018-03-05T12:32:08.000Z",
"complaintId": 2
}
]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.8/angular-filter.min.js"></script>
<div ng-app="app">
<div ng-controller="test">
<table>
<tr ng-repeat="item in items | unique: 'complaintId'">
<td>{{$index + 1}}</td>
<td>{{item.status}}</td>
</tr>
</table>
</div>
</div>
Try using loadash lib.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="c in times">
{{c.complaintId}} - {{c.time}}
</div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.times= [{
"id": 1,
"status": true,
"time": "2018-03-05T10:24:15.000Z",
"complaintId": 1
},
{
"id": 3,
"status": true,
"time": "2018-03-05T10:53:14.000Z",
"complaintId": 2
},
{
"id": 6,
"status": false,
"time": "2018-03-05T11:58:45.000Z",
"complaintId": 1
},
{
"id": 7,
"status": true,
"time": "2018-03-05T12:11:53.000Z",
"complaintId": 1
},
{
"id": 8,
"status": false,
"time": "2018-03-05T13:23:13.000Z",
"complaintId": 2
},
{
"id": 9,
"status": true,
"time": "2018-03-05T08:17:18.000Z",
"complaintId": 3
},
{
"id": 10,
"status": true,
"time": "2018-03-05T12:32:08.000Z",
"complaintId": 2
}
];
$scope.times = _.sortBy($scope.times,'time').reverse();
$scope.times= _.uniqBy($scope.times, 'complaintId');
// console.log($scope.times);
});
</script>
</body>
</html>
I have started with reacr-redux. in that I have got some json data to populate as table structure. for that I have data like this
[
{
"year": 2016,
"mix": [{
"name": "A",
"volume": 0.55,
},
{
"name": "B",
"volume": 0.2,
},
{
"name": "C",
"volume": 0.0,
},
{
"name": "D",
"volume": 0.0,
}],
},
{
"year": 2017,
"mix": [{
"name": "A",
"volume": 0.55,
},
{
"name": "B",
"volume": 0.2,
},
{
"name": "C",
"volume": 0.0,
},
{
"name": "D",
"volume": 0.0,
}],
},
{
"year": 2018,
"mix": [{
"name": "A",
"volume": 0.55,
},
{
"name": "B",
"volume": 0.2,
},
{
"name": "C",
"volume": 0.0,
},
{
"name": "D",
"volume": 0.0,
}],
},
{
"year": 2015,
"mix" :[{
"name": "A",
"volume": 0.55,
},
{
"name": "B",
"volume": 0.2,
},
{
"name": "C",
"volume": 0.0,
},
{
"name": "D",
"volume": 0.0,
}]
},
{
"year": 2019,
"mix": [
{
"name": "A",
"volume": 0.55,
},
{
"name": "B",
"volume": 0.2,
},
{
"name": "C",
"volume": 0.0,
},
{
"name": "D",
"volume": 0.0,
}
],
}
]
and I want my table structure like this. basically it extracts year and of that year all the mix. so final table structure should look like this
2015 2016 2017 2018
A 0.55 0.55 0.55 0.55
B 0.2 0.2 0.2 0.2
C 0 0 0 0
D 0 0 0 0
for that I have written code like this
<table className="table table-bordered">
<thead>
<tr>
<th></th>
{this.props.allYear.map((data) =>(
<th>{data.year.toString().substr(0,4)}</th>
))}
</tr>
</thead>
<tbody>
{this.props.allYear.map((data) =>(
data.mix.map((Data1) => (
<tr>
{Data1.name}
</tr>
))
))}
<td></td>
{this.props.allYear.map((data) =>(
<td>
{data.mix.map((Data1) => {
return(
<tr>
{Data1.volume}
</tr>
)
})}
</td>
))}
</tbody>
</table>
but my all the data went 1 tr down because of the tr I have written so table looks like this
2015 2016 2017 2018
A
B
C
D
0.55 0.55 0.55 0.55
0.2 0.2 0.2 0.2
0 0 0 0
0 0 0 0.
Please let me know how to fix this
I figured out a way to keep your original data structure:
var sorted = this.props.allYear.sort((a, b) => a.year - b.year);
// create rows object, letters as keys, each value an array of volumes
var rows = {};
sorted.forEach(function (year) {
year.mix.forEach((data) => {
if (!rows[data.name]) rows[data.name] = [];
rows[data.name].push(data.volume);
});
});
return (
<table className="table table-bordered">
<thead>
<tr>
<th></th>
{sorted.map((data, i) => <th key={i}>{data.year}</th>)}
</tr>
</thead>
<tbody>
{Object.keys(rows).map((letter) =>
<tr>
<td>{letter}</td>
{rows[letter].map((data) => <td>{data}</td>)}
</tr>
)}
</tbody>
</table>
);
However this assumes that there are no "holes" in the data.
Your table structure is all kinds of wrong. What you are doing is creating 4 <tr> and then a bunch of random <td>. Basic table structure is table -> tbody -> tr -> td. You need to create two map functions. Like Chris G mentioned in a comment, your data structure is not setup to make this easy. It actually makes what you want to do a lot harder. I would suggest changing your data structure to something more like this:
[
A: [{
year: 2015,
volume: 0.0
},{
year: 2016,
volume: 0.0
},{
year: 2017,
volume: 0.0
}],
B: [{
year: 2015,
volume: 0.0
},{
year: 2016,
volume: 0.0
},{
year: 2017,
volume: 0.0
}],
C: ...
]
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
How i can parse this json
[
{"CODE":"1","MONTH":"1","TOTAL":78},
{"CODE":"1","MONTH":"2","TOTAL":122},
{"CODE":"1","MONTH":"3","TOTAL":102},
{"CODE":"1","MONTH":"4","TOTAL":65},
{"CODE":"1","MONTH":"5","TOTAL":134},
{"CODE":"1","MONTH":"6","TOTAL":88},
{"CODE":"1","MONTH":"7","TOTAL":77},
{"CODE":"1","MONTH":"8","TOTAL":58},
{"CODE":"1","MONTH":"9","TOTAL":67},
{"CODE":"1","MONTH":"10","TOTAL":69},
{"CODE":"2","MONTH":"5","TOTAL":4},
{"CODE":"2","MONTH":"6","TOTAL":87},
{"CODE":"2","MONTH":"7","TOTAL":81},
{"CODE":"2","MONTH":"8","TOTAL":105},
{"CODE":"2","MONTH":"9","TOTAL":112},
{"CODE":"2","MONTH":"10","TOTAL":85},
]
To this format
series: [{
name: '1',
data: [78, 122, 102, 65, 134, 88, 77, 58, 67, 69, 0, 0]
}, {
name: '2',
data: [0, 0, 0, 0, 4, 87, 81, 105, 112, 85, 0, 0]
}]
With an javascript or jquery function efficiently?
In the Json every row represents a total value for each code (1 or 2) per month
For the CODE=1 i have totals only for ten months (month 1 = jan, month 2= feb ... month 10= oct)
For the CODE=2 i have totals only for five months between may and octuber.
In this array [78, 122, 102, 65, 134, 88, 77, 58, 67, 69, 0, 0]
78 is the total for january, 122 for february, 102 for march ...
For those months that i do not have a total, like november or december for example , i need to put a 0
My json will return more info, with more codes i can't use brute force
Thanks in advance
JC
You can run a loop like the following:
var temp = [];
for (var i =0; i< data.length;i++) {
var obj = data[i],
dup = false;
for (var j = 0; j < temp.length; j++) {
var item = temp[j];
if (obj.CODE == item.name) {
item.data.push(obj.TOTAL);
dup = true;
break;
}
}
if (!dup) {
temp.push({
name: obj.CODE,
data: [obj.TOTAL]
});
}
}
var data = [{
"CODE": "1",
"MONTH": "1",
"TOTAL": 78
}, {
"CODE": "1",
"MONTH": "2",
"TOTAL": 122
}, {
"CODE": "1",
"MONTH": "3",
"TOTAL": 102
}, {
"CODE": "1",
"MONTH": "4",
"TOTAL": 65
}, {
"CODE": "1",
"MONTH": "5",
"TOTAL": 134
}, {
"CODE": "1",
"MONTH": "6",
"TOTAL": 88
}, {
"CODE": "1",
"MONTH": "7",
"TOTAL": 77
}, {
"CODE": "1",
"MONTH": "8",
"TOTAL": 58
}, {
"CODE": "1",
"MONTH": "9",
"TOTAL": 67
}, {
"CODE": "1",
"MONTH": "10",
"TOTAL": 69
},
{
"CODE": "2",
"MONTH": "5",
"TOTAL": 4
}, {
"CODE": "2",
"MONTH": "6",
"TOTAL": 87
}, {
"CODE": "2",
"MONTH": "7",
"TOTAL": 81
}, {
"CODE": "2",
"MONTH": "8",
"TOTAL": 105
}, {
"CODE": "2",
"MONTH": "9",
"TOTAL": 112
}, {
"CODE": "2",
"MONTH": "10",
"TOTAL": 85
}
];
var temp = [];
for (var i = 0; i < data.length; i++) {
var obj = data[i],
dup = false;
for (var j = 0; j < temp.length; j++) {
var item = temp[j];
if (obj.CODE == item.name) {
item.data.push(obj.TOTAL);
dup = true;
break;
}
}
if (!dup) {
temp.push({
name: obj.CODE,
data: [obj.TOTAL]
});
}
}
console.log(temp);
<p>Check browser console <sup>F12</sup> to see the result<p>
Here is a brute force example which does only what was requested.
working jsfiddle
var originalData = [
{"CODE":"1","MONTH":"1","TOTAL":78},
{"CODE":"1","MONTH":"2","TOTAL":122},
{"CODE":"1","MONTH":"3","TOTAL":102},
{"CODE":"1","MONTH":"4","TOTAL":65},
{"CODE":"1","MONTH":"5","TOTAL":134},
{"CODE":"1","MONTH":"6","TOTAL":88},
{"CODE":"1","MONTH":"7","TOTAL":77},
{"CODE":"1","MONTH":"8","TOTAL":58},
{"CODE":"1","MONTH":"9","TOTAL":67},
{"CODE":"1","MONTH":"10","TOTAL":69},
{"CODE":"2","MONTH":"5","TOTAL":4},
{"CODE":"2","MONTH":"6","TOTAL":87},
{"CODE":"2","MONTH":"7","TOTAL":81},
{"CODE":"2","MONTH":"8","TOTAL":105},
{"CODE":"2","MONTH":"9","TOTAL":112},
{"CODE":"2","MONTH":"10","TOTAL":85},
];
var newData={};
var tempData1=[];
var tempData2=[];
for (var ii=0;ii<originalData.length;ii++){
if (originalData[ii].CODE==="1"){
tempData1.push(originalData[ii].TOTAL);
}
else{
tempData2.push(originalData[ii].TOTAL);
}
}
newData['series'] =[ {name: '1',
data: tempData1},
{
name: '2',
data: tempData2
}];
console.log(JSON.stringify(newData));
var oData = [
{"CODE":"1","MONTH":"1","TOTAL":78},
{"CODE":"1","MONTH":"2","TOTAL":122},
{"CODE":"1","MONTH":"3","TOTAL":102},
{"CODE":"1","MONTH":"4","TOTAL":65},
{"CODE":"1","MONTH":"5","TOTAL":134},
{"CODE":"1","MONTH":"6","TOTAL":88},
{"CODE":"1","MONTH":"7","TOTAL":77},
{"CODE":"1","MONTH":"8","TOTAL":58},
{"CODE":"1","MONTH":"9","TOTAL":67},
{"CODE":"1","MONTH":"10","TOTAL":69},
{"CODE":"2","MONTH":"5","TOTAL":4},
{"CODE":"2","MONTH":"6","TOTAL":87},
{"CODE":"2","MONTH":"7","TOTAL":81},
{"CODE":"2","MONTH":"8","TOTAL":105},
{"CODE":"2","MONTH":"9","TOTAL":112},
{"CODE":"2","MONTH":"10","TOTAL":85},
],
nData = [{ name: '1', data: [] }, { name: '2', data: [] }];
for (var n = 1; n <= 12; n++) {
var d1 = oData.filter(function(d) {
return d.CODE == '1' && d.MONTH == n;
}),
d2 = oData.filter(function(d) {
return d.CODE == '2' && d.MONTH == n;
});
nData[0].data.push(d1.length ? d1[0].TOTAL : 0);
nData[1].data.push(d2.length ? d2[0].TOTAL : 0);
}
$('pre.out').text( JSON.stringify(nData) );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre class="out"></pre>