Getting PHP multidimensional array in to Javascript using JSON? - javascript

I need to get an array to display the following way:
var categories = data.categories;
for(a = 0; a < data.count; a++){
var names[a] = data.name[a];
var values[a] = data.value[a];
}
There will be one "Categories" array, for example "May 2017","June 2017","July 2017","August 2017","September 2017". Then there may be 3/4 arrays containing "Name" and "Values" and I want these to loop through a loop to loop and assign these to variables.
At the moment I'm getting 'Undefined" in all variables.
My output in php is currently:
[
[{
"name": "Leads",
"data": [524, 419, 502, 598, 873],
"color": "#00afef"
}, {
"name": "Purchases",
"data": [37, 18, 32, 36, 44],
"color": "#f00"
}], {
"categories": ["May 2017", "June 2017", "July 2017", "August 2017", "September 2017"]
}
]

The JSON you're getting back has horrible schema and you're doing weird things in JS. Hopefully the following will get you back on track:
var data = [
[{
"name": "Leads",
"data": [524, 419, 502, 598, 873],
"color": "#00afef"
}, {
"name": "Purchases",
"data": [37, 18, 32, 36, 44],
"color": "#f00"
}], {
"categories": ["May 2017", "June 2017", "July 2017", "August 2017", "September 2017"]
}
];
var categories = data[1].categories;
var names = [];
var values = [];
for (var a = 0; a < data[0].length; a++) {
names.push(data[0][a].name);
values.push(data[0][a]);
}
console.log(categories);
console.log(names);
console.log(values);

Related

JavaScript sort a dictionary array

I have a question about sorting a dictionary object is JS es6. I am trying to filter the array but still keep the structure of an array in each month's object. Here is a mock of the data:
"soldListings": {
"Jan - 2020": [
{
"id": 159,
"user_id": 1,
"type_id": 1,
},
{
"id": 173,
"user_id": 1,
"type_id": 1,
},
{
"id": 563,
"user_id": 1,
"type_id": 2,
}
],
"Dec - 2019": [
{
"id": 183,
"user_id": 1,
"type_id": 1,
}
],
"Oct - 2019": [
{
"id": 176,
"user_id": 1,
"type_id": 1,
}
]
}
If it were a flat array of objects i would do something like:
typeFilter = data.filter((listing) => {
if(listing.type_id){
return listing.type_id == this.state.soldListTypeFilter ;
}
});
UPDATE
I need the output to be in the same format as the input. For example if i were to filter the object by type_id = 2 it would return this:
"soldListings": {
"Jan - 2020": [
{
"id": 563,
"user_id": 1,
"type_id": 2,
}
],
"Dec - 2019": [
],
"Oct - 2019": [
]
}
Use keySort function for this problem, for un-integer keys
Read https://stackoverflow.com/a/23202095/7146552
keySort( object, sortfn? )
function keySort(obj, sort) {
var keys = Object.keys(obj);
keys = keys.sort(sort);
var sortedObject = {};
for (var i = 0; i < keys.length; i++) {
sortedObject[keys[i]] = obj[keys[i]]
}
return sortedObject;
}
// Using
var obj = {
"z:": "Zvalue",
"a": "AValue"
};
console.log(obj);
obj = keySort(obj);
// or
obj = keySort(obj, (a, b) => {
return a > b ? 1 : -1
});
console.log(obj)
On your Question Test
function keySort(obj, sort) {
var keys = Object.keys(obj);
keys = keys.sort(sort);
var sortedObject = {};
for (var i = 0; i < keys.length; i++) {
sortedObject[keys[i]] = obj[keys[i]]
}
return sortedObject;
}
data = {
"Jan - 2020": [{
"id": 159,
"user_id": 1,
"type_id": 1,
},
{
"id": 173,
"user_id": 1,
"type_id": 1,
},
{
"id": 563,
"user_id": 1,
"type_id": 2,
}
],
"Dec - 2019": [{
"id": 183,
"user_id": 1,
"type_id": 1,
}],
"Oct - 2019": [{
"id": 176,
"user_id": 1,
"type_id": 1,
}]
}
data = keySort(data,function(a,b){
adate = new Date(a);
bdate = new Date(b);
return adate>bdate ? 1 : -1;
})
console.log(data);

Merge specific array values into single value

I have parsed a csv file which gives me an array like this:
[{
"year": 2019,
"month": 6,
"day": 25,
"hour": 4,
"minute": 0,
"temperature": 26.52
},
{
"year": 2019,
"month": 6,
"day": 25,
"hour": 4,
"minute": 0,
"temperature": 26.52
}]
I want to merge minute,hour,day,month,year to a single key. Like this:
"time": "2019-07-02 09:57:35"
so i can use this as a datetime object on my API.
The way I am currently getting data is:
const cleanKeys = [
'year',
'month',
'day',
'hour',
'minute',
'temperature',
];
const dataAsObject = totalData.map(function (values) {
return cleanKeys.reduce(function (o, k, i) {
o[k] = values[i];
return o;
}, {})
});
This is basically adding a header key to all data. I am only interested in merging minute, hour, day, month, year column.
I suggest you to use built in Date constructor:
var obj = {"year": 2019,
"month": 6,
"day": 25,
"hour": 4,
"minute": 0,
"temperature": 26.52};
const date = new Date(obj.year, obj.month - 1, obj.day, obj.hour, obj.minute);
const newObj = {date, temperature: obj.temperature};
console.log(JSON.stringify(newObj));
EDIT:
please find below updated answer using date in loop:
const arr = [{
"year": 2019,
"month": 6,
"day": 25,
"hour": 4,
"minute": 0,
"temperature": 26.52
},
{
"year": 2019,
"month": 6,
"day": 25,
"hour": 4,
"minute": 0,
"temperature": 26.52
}];
const newArr = arr.reduce((a,c) => {
const date = new Date(c.year, c.month - 1, c.day, c.hour, c.minute);
a.push({date, temperature: c.temperature});
return a;
}, []);
console.log(JSON.stringify(newArr));
You can create the string yourself, e.g.:
yourArray["time"] = `${yourArray.year}-${yourArray.month}-${yourArray.day} ${yourArray.hours}:${yourArray.minutes}:${yourArray.seconds}`;

How to read values and sum over a dynamic array?

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)

Object Array Elements gets modifed on Push

I have an empty Array
var kpi_arr = [];
I push in an Object
{
kpi_id: "18",
kpi_name: "CSAT",
kpi_target: "7",
kpi_months: [
{
monthname: "Aug 2017",
month_value: "",
month_id: "201",
month_kpi: "18"
},
{
monthname: "Sep 2017",
month_value: "",
month_id: "301",
month_kpi: "18"
}
]
}
The Array now has one object with the correct values. However when i push in a second object
{
kpi_id: "16",
kpi_name: "Updated handbooks",
kpi_target: " 100%",
kpi_months: [
{
monthname: "Aug 2017",
month_value: "",
month_id: "201",
month_kpi: "16"
},
{
monthname: "Sep 2017",
month_value: "",
month_id: "301",
month_kpi: "16"
}
]
}
the array content appears as below
[
{
kpi_id: "18",
kpi_name: "CSAT",
kpi_target: "7",
kpi_months: [
{
monthname: "Aug 2017",
month_value: "",
month_id: "201",
month_kpi: "16"
},
{
monthname: "Sep 2017",
month_value: "",
month_id: "301",
month_kpi: "16"
}
]
},
{
kpi_id: "16",
kpi_name: "Updated handbooks",
kpi_target: " 100%",
kpi_months: [
{
monthname: "Aug 2017",
month_value: "",
month_id: "201",
month_kpi: "16"
},
{
monthname: "Sep 2017",
month_value: "",
month_id: "301",
month_kpi: "16"
}
]
}
]
Note that all month_kpi property values change to 16.
What could be the reason for this?
I'm pushing these objects into the array via a for-loop in the format below.
var rolling_months_arr = get_rolling_13month_period();
var kpi_arr = [];
for(){
var month_kpi = getValueFromWherever();
var myobject = getObject(rolling_months_arr, month_kpi)
kpi_arr.push(myobject )
}
//------------------------------------------
function getObject(rolling_months_arr, month_kpi)
{
for ( var i = 0; i < rolling_months_arr.length; i++)
{
rolling_months_arr[i].month_kpi = month_kpi;
}
return rolling_months_arr;
}
function get_rolling_13month_period()
{
var month_arr = [];
for(){
month_arr.push({ "monthname": rolling_month, "month_id": month_id });
}
return month_arr;
}
rolling_months_arr is being reused, you need to create a new one inside the for()
you are using the same rolling_months_arr each time you add to the array.push, so the values are changed in all instances
put var rolling_months_arr = get_rolling_13month_period(); inside the for()
or clone that var:
for(){
var month_kpi = getValueFromWherever();
rolling_months_arr = _.cloneDeep(rolling_months_arr); //<= cloneDeep
var myobject = getObject(rolling_months_arr, month_kpi)
kpi_arr.push(myobject )
}

Having trouble formatting this JSON data from the server

I'm creating a section of a site in Angular JS that displays some reporting data from the server. Since I'm displaying it in a table I need it in a format that can easily be displayed with ng-repeat.
I therefore need to translate JSON data from the server into a JavaScript object. I've got the target format of the data I want, an object that uses the names of the 'Donor Programs' as keys, and as their values an array of objects that each correspond to a month. Each of the objects has the name of the month, the amount of people who registered on the site, the amount of those people who donated, and the total amount donated.
I'm just having a really hard time iterating through the JSON and getting it to translate to that format. Can someone have a look? I've included both the server data I'm getting as well as how I'm trying to format it. Thanks.
Server Data:
$scope.serverData = {
"registration_by_month": [
{
"month": "November 2015",
"registration_program": "Donor Program 1",
"count": 3
},
{
"month": "November 2015",
"registration_program": "Donor Program 2",
"count": 4
},
{
"month": "December 2015",
"registration_program": "Donor Program 1",
"count": 5
},
{
"month": "December 2015",
"registration_program": "Donor Program 2",
"count": 6
}
],
"donors_by_month": [
{
"month": "November 2015",
"registration_program": "Donor Program 1",
"count": 2
},
{
"month": "November 2015",
"registration_program": "Donor Program 2",
"count": 1
},
{
"month": "December 2015",
"registration_program": "Donor Program 1",
"count": 2
},
{
"month": "December 2015",
"registration_program": "Donor Program 2",
"count": 1
}
],
"donated_amount_by_month": [
{
"month": "November 2015",
"registration_program": "Donor Program 1",
"amount": 100
},
{
"month": "November 2015",
"registration_program": "Donor Program 2",
"amount": 200
},
{
"month": "December 2015",
"registration_program": "Donor Program 1",
"amount": 50
},
{
"month": "December 2015",
"registration_program": "Donor Program 2",
"amount": 40
}
]
};
Target Data:
$scope.targetData = {
"Donor Program 1": [{month:"November 2015", registered:3, donors:2, donated_amount:100},{month:"December 2015", registered:4, donors:1, donated_amount:200}],
"Donor Program 2:": [{month:"November 2015", registered:5, donors:2, donated_amount:50},{month:"December 2015",registered:6, donors:1, donated_amount:40}]
};
Try like this
var temp = {};
data.registration_by_month.forEach(function (x) {
if (!temp[x.registration_program]) {
temp[x.registration_program] = [];
}
var dtmon = data.donors_by_month.find(function (y) {
return y.registration_program == x.registration_program;
});
var dnmon = data.donated_amount_by_month.find(function (y) {
return y.registration_program == x.registration_program;
});
temp[x.registration_program].push({
month: x.month,
registered: x.count,
donors: dtmon ? dtmon.count : 0,
donated_amount: dnmon ? dnmon.amount : 0
});
});
console.log(temp);
JSFIDDLE
EDIT
.find is not supported in IE and opera.
You can try .filter instead
Like this
var temp = {};
data.registration_by_month.forEach(function (x) {
if (!temp[x.registration_program]) {
temp[x.registration_program] = [];
}
var dtmon = data.donors_by_month.filter(function (y) {
return y.registration_program == x.registration_program;
});
var dnmon = data.donated_amount_by_month.filter(function (y) {
return y.registration_program == x.registration_program;
});
temp[x.registration_program].push({
month: x.month,
registered: x.count,
donors: dtmon.length > 0 ? dtmon[0].count : 0,
donated_amount: dnmon.length > 0 ? dnmon[0].amount : 0
});
});
JSFIDDLE

Categories

Resources