Having trouble formatting this JSON data from the server - javascript

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

Related

Is it possible to pass a parameter which pertains to relation field in custom controller in Strapi Version 4?

I am learning Strapi in version 4. I have following two content-types:
employee with name and dept of an employee with relation salaries
salary with month, year, salaryAmount and relation employee
One employee can have many salaries for different months and years. There are three employees with
salaries of January to March 2022. So, salary content-type has nine records. Both the content-types are public.
What I am trying to attain is create a custom controller which can give data of all salaries of a
particular employee. For example if I pass employee id in browser query like
http://localhost:1337/api/empsalary/2 the response should give me three salaries of an employee
with id 2 for three months January to March 2022.
My code for controller salary.js reads as under:
'use strict';
const { createCoreController } = require('#strapi/strapi').factories;
module.exports = createCoreController('api::salary.salary', ({strapi})=>({
async empsalary (ctx){
const { id } = ctx.params;
const entity = await strapi.service('api::salary.salary').find( { employee : id } ) // pass employee id as parameter to find()
const sEntity = await this.sanitizeOutput(entity, ctx)
return this.transformResponse(sEntity)
},
}) );
The custom path file named empsalary.js reads as under:
module.exports ={
routes: [
{
method: 'GET',
path: '/empsalary/:id',
handler: 'salary.empsalary',
config: { auth : false, }
},
]
}
The result I get is as under:
{
"data": {
"attributes": {
"results": [
{
"id": 1,
"month": "January",
"year": 2022,
"salaryAmount": 65000,
"createdAt": "2022-09-21T10:36:18.314Z",
"updatedAt": "2022-09-21T10:36:19.870Z",
"publishedAt": "2022-09-21T10:36:19.866Z"
},
{
"id": 2,
"month": "January",
"year": 2022,
"salaryAmount": 50000,
"createdAt": "2022-09-21T10:36:51.059Z",
"updatedAt": "2022-09-21T10:36:56.643Z",
"publishedAt": "2022-09-21T10:36:56.640Z"
},
{
"id": 3,
"month": "January",
"year": 2022,
"salaryAmount": 40000,
"createdAt": "2022-09-21T10:37:33.949Z",
"updatedAt": "2022-09-21T10:37:35.290Z",
"publishedAt": "2022-09-21T10:37:35.288Z"
},
{
"id": 4,
"month": "February",
"year": 2022,
"salaryAmount": 70000,
"createdAt": "2022-09-21T10:39:19.440Z",
"updatedAt": "2022-09-21T10:39:21.160Z",
"publishedAt": "2022-09-21T10:39:21.158Z"
},
{
"id": 5,
"month": "February",
"year": 2022,
"salaryAmount": 60000,
"createdAt": "2022-09-21T10:39:52.514Z",
"updatedAt": "2022-09-21T10:39:54.246Z",
"publishedAt": "2022-09-21T10:39:54.244Z"
},
{
"id": 6,
"month": "February",
"year": 2022,
"salaryAmount": 40000,
"createdAt": "2022-09-21T10:40:29.293Z",
"updatedAt": "2022-09-21T10:41:10.671Z",
"publishedAt": "2022-09-21T10:40:30.679Z"
},
{
"id": 7,
"month": "March",
"year": 2022,
"salaryAmount": 75000,
"createdAt": "2022-09-21T10:43:01.475Z",
"updatedAt": "2022-09-21T10:43:03.085Z",
"publishedAt": "2022-09-21T10:43:03.082Z"
},
{
"id": 8,
"month": "March",
"year": 2022,
"salaryAmount": 60000,
"createdAt": "2022-09-21T10:43:41.065Z",
"updatedAt": "2022-09-21T10:43:42.480Z",
"publishedAt": "2022-09-21T10:43:42.478Z"
},
{
"id": 9,
"month": "March",
"year": 2022,
"salaryAmount": 50000,
"createdAt": "2022-09-21T10:44:12.663Z",
"updatedAt": "2022-09-21T10:44:14.162Z",
"publishedAt": "2022-09-21T10:44:14.160Z"
}
],
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 9
}
}
},
"meta": {}
}
The response gives me data of all nine salaries instead of only three salaries
of a particular employee.
Is there anything fundamentally wrong in my approach or even my code?
Please guide me. Thanks.

how to create a separate array of json object having common id

hello every one i have situation and needs your help , i have json array having common id firstly i need to take common id from all json obj and then place each common json to separate array
var myArray = [ {"id" : 1, "text": "Number one", "time": "16 03 13"},{"id" : 1, "text": "Number two", "time": "14 03 13"},{"id" : 1, "text": "Number three", "time": "13 03 13"},{"id" : 2, "text": "Number one", "time": "13 03 13"}]
I want output of this object as
var myArray = {
[
"1" : [
{"text": "Number one", "time": "16 03 13"},
{"text": "Number two", "time": "14 03 13"},
{"text": "Number three", "time": "13 03 13"}
]
]
[
"2" : [
{"text": "Number one", "time": "13 03 13"}
]
]}
I want to place common ID in a each separate JSON array to make 2d array
var myArray = [ {"id" : 1, "text": "Number one", "time": "16 03 13"},{"id" : 1, "text": "Number two", "time": "14 03 13"},{"id" : 1, "text": "Number three", "time": "13 03 13"},{"id" : 2, "text": "Number one", "time": "13 03 13"}]
const uniqueIds = myArray.map(elem=>elem.id).filter((value, index, self)=>self.indexOf(value) === index)
const contentsOfId = (id)=>{
return myArray.filter(elem=>elem.id === id).map(({text,time})=>({text,time}))
}
const results = uniqueIds.map(id =>{
const obj={}
obj[id]=contentsOfId(id);
return obj;
})
The Output will be
[{"1":[{"text":"Number one","time":"16 03 13"},{"text":"Number two","time":"14 03 13"},{"text":"Number three","time":"13 03 13"}]},{"2":[{"text":"Number one","time":"13 03 13"}]}]
Instead of having multiple loops you can achieve this linearly.
var myArray = [{ "id": 1, "text": "Number one", "time": "16 03 13" }, { "id": 1, "text": "Number two", "time": "14 03 13" }, { "id": 1, "text": "Number three", "time": "13 03 13" }, { "id": 2, "text": "Number one", "time": "13 03 13" }]
const outputArray = {}
myArray.forEach((ele)=>{
if(outputArray[ele.id]){
outputArray[ele.id] = [...outputArray[ele.id], {...ele}]
} else {
outputArray[ele.id] = [ele]
}
});
console.log(outputArray)
The Output will be
{ '1':[ { id: 1, text: 'Number one', time: '16 03 13' },
{ id: 1, text: 'Number two', time: '14 03 13' },
{ id: 1, text: 'Number three', time: '13 03 13' }
],
'2': [ { id: 2, text: 'Number one', time: '13 03 13' } ]
}

Javascript get value in json based on another value

I have a json similar to this one
{
"id": "1",
"month": "January",
"type": "inc",
"Value": "780.00",
"year": "2018",
},
{
"id": "2",
"month": "January",
"type": "inc",
"Value": "80.00",
"year": "2018",
},
{
"id": "3",
"month": "February",
"type": "inc",
"Value": "100.00",
"year": "2018",
},...
Now I need to get all the Value from the object for all the months, as you can see I may have more objects with the same month name. The closer I got to was creating 2 arrays 1 with the list of Months and 1 with the value but I got stuck, can someone lead me to the correct path?
The desired output would be to get an array like that ["January"=>1500, "February"=>2000...] or have 2 arrays, 1 with the list of months where there is income (I already have it) and the second the total income for these months, so it's like this: ["January", "February", "March"..] and the second one [1500, 2000, 300...]
You can use the function Array.prototype.reduce to sum each Value by month.
let arr = [{ "id": "1", "month": "January", "type": "inc", "Value": "780.00", "year": "2018", }, { "id": "2", "month": "January", "type": "inc", "Value": "80.00", "year": "2018", }, { "id": "3", "month": "February", "type": "inc", "Value": "100.00", "year": "2018", }],
result = arr.reduce((a, {month, Value}) => {
a[month] = (a[month] || 0) + +Value;
return a;
}, Object.create(null));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I actually can barely understand what you would like to achieve. Please provide some example.
If I understood you correctly, you can use map function of js array to map each object to its Value.
let arr = [...];
console.log(arr.map(item => item.Value));
You can do
var fabuaryDate = yourdata
.filter(function(data) { return data.month == "February" })
.map(function(x){return {value: x.Value} })
To get result in following format :
{
jan : [1,2,3],
feb : [3,4,5,6],
april : [3,4,5]
}
do this :
var output = {}
arr.forEach(element => {
if(!output[element.month]){
output[month] = new Array();
}
output[month].push(element.value);
});
You can iterate the object and fill an array with the values of the field you want to extract, like so:
const data = [ {
"id": "1",
"month": "January",
"type": "inc",
"Value": 780.00,
"year": "2018",
},
{
"id": "2",
"month": "January",
"type": "inc",
"Value": 80.00,
"year": "2018",
},
{
"id": "3",
"month": "February",
"type": "inc",
"Value": 100.00,
"year": "2018",
}];
let dataArray = data.reduce((accum, d) => {
if(!accum[d.month]) accum[d.month] = 0;
accum[d.month] += d.Value;
return accum;
},{});
console.log(dataArray);
Although you don't seem to be clear enough with what have you tried here is an example of what you could do in order to read all the values inside the json.
function myFunction(item) {
console.log(item.month + " with the value " + item.Value)
}
var jsonArray = [{"id": "1","month": "January", "type": "inc", "Value": "780.00", "year": "2018" }, { "id": "2", "month": "January", "type": "inc", "Value": "80.00", "year": "2018" }, { "id": "3", "month": "February", "type": "inc", "Value": "100.00", "year": "2018" }];
jsonArray.forEach(myFunction);
Since you're working with an array of objects you must access to each of the objects in the array and then get the attribute that you require.
Hope this help, have a great day.

Keys problems when mapping using Lodash

I am trying to get my monthly sales and put them on the chart. They're going to be grouped by year. This is what I've done so far:
let result = _
.chain(res.data)
.groupBy("_id.year")
.value();
result = _.map(result, (yearlyValues, key) => {
return {
[key]: _.map(yearlyValues, yearlyValuesItems => {
return {
[yearlyValuesItems._id.month]: yearlyValuesItems.count
};
})
};
});
result = _.map(result, (value, key) => {
return _.map(value, (innerValues, innerKey) => {
return innerValues;
})
})
result = _.flatten(result);
result = _.map(result, (value, key) => {
return _.map(value, (items, keys) => {
return _.map(items, (a, b) => {
return a
})
})
});
for (var i in result) {
final_count.push(_.flatten(result[i]));
}
console.log(final_count);
$scope.labels_monthly = monthNames;
$scope.series = Object.keys(final_count);
$scope.data = Object.values(final_count);
$scope.options = {
legend: {
display: true
}
};
My data: https://pastebin.com/WhJ0atTX
My output: https://jsfiddle.net/asfxtor4/1/
My problem is that I am getting keys 0, 1, 2 instead of 2016, 2017, 2018.
And then inside I need to get key as a month number.This key has to be 2 because the month is March, but it generates 0. You can see in the pictures.
This is my desired output: https://pastebin.com/iChhrnNG, I need to get an array of all months and if there is data for just March lets say, all other array elements should be 0.
You can get an array of objects with years and values by adding 'entries' e.g.
let result = _
.chain(data)
.groupBy("_id.year")
.entries()
.value()
.map((item) => ({year: item[0], values: item[1]}));
You then won't need:
result = _.map(result, (yearlyValues, key) => {
return {
[key]: _.map(yearlyValues, yearlyValuesItems => {
return {
[yearlyValuesItems._id.month]: yearlyValuesItems.count
};
})
};
});
You can see a fiddle here:
https://jsfiddle.net/Fresh/yr8bqteL/
Hopefully this info will help you complete this assignment.
Since you know you always have 12 months you could be somewhat less fancy and do this:
data = [{
"_id": {
"month": 12,
"year": 2018
},
"count": 3
},
{
"_id": {
"month": 11,
"year": 2018
},
"count": 4
},
{
"_id": {
"month": 9,
"year": 2018
},
"count": 3
},
{
"_id": {
"month": 8,
"year": 2018
},
"count": 4
},
{
"_id": {
"month": 5,
"year": 2018
},
"count": 4
},
{
"_id": {
"month": 7,
"year": 2018
},
"count": 2
},
{
"_id": {
"month": 4,
"year": 2018
},
"count": 5
},
{
"_id": {
"month": 9,
"year": 2017
},
"count": 2
},
{
"_id": {
"month": 8,
"year": 2017
},
"count": 4
},
{
"_id": {
"month": 11,
"year": 2017
},
"count": 4
},
{
"_id": {
"month": 10,
"year": 2017
},
"count": 3
},
{
"_id": {
"month": 4,
"year": 2017
},
"count": 2
},
{
"_id": {
"month": 2,
"year": 2017
},
"count": 3
},
{
"_id": {
"month": 6,
"year": 2017
},
"count": 1
},
{
"_id": {
"month": 1,
"year": 2018
},
"count": 4
},
{
"_id": {
"month": 2,
"year": 2018
},
"count": 4
},
{
"_id": {
"month": 3,
"year": 2018
},
"count": 9
},
{
"_id": {
"month": 10,
"year": 2018
},
"count": 3
},
{
"_id": {
"month": 3,
"year": 2017
},
"count": 9
},
{
"_id": {
"month": 7,
"year": 2017
},
"count": 2
},
{
"_id": {
"month": 12,
"year": 2017
},
"count": 3
},
{
"_id": {
"month": 3,
"year": 2016
},
"count": 1
},
{
"_id": {
"month": 1,
"year": 2017
},
"count": 3
},
{
"_id": {
"month": 6,
"year": 2018
},
"count": 3
}
]
let result = _
.chain(data)
.groupBy("_id.year")
.reduce((obj, current, index) => {
var sortedMonths = _.sortBy(current, (v) => v._id.month), monthsArray = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
_.map(current, (curObj, i) => monthsArray[_.get(sortedMonths, '[' + i + ']._id.month') - 1] = sortedMonths[i].count)
return _.extend(obj, { [index]: monthsArray })
}, {})
.value();
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

How can i get Json format data through jquery

i am trying to get the value of count and year but unable to get. I have tried this so far.
[
[{
"count": 130,
"year": "Week 1"
}],[{
"count": 160,
"year": "Week 2"
}],[{
"count": 190,
"year": "Week 3"
}]
]
var parsedData = JSON.parse(data);
alert(parsedData.count);
alert(parsedData[0].count);
alert(parsedData[0].year);
parseddata is a 2 dimensional array. Try accessing the data like this.
var data = '[[{"count":130,"year":"Week 1"}],[{"count":160,"year":"Week 2"}],[{"count":190,"year":"Week 3"}]]';
var parseddata = JSON.parse(data);
console.log(parseddata[0][0].count);
console.log(parseddata[0][0].year);
As #Rory McCrossan mentioned, your JSON is too messy. It can be simple as below.
var data = [{
"count": 130,
"year": "Week 1"
}, {
"count": 160,
"year": "Week 2"
}, {
"count": 190,
"year": "Week 3"
}];
console.log(data[0].count);
console.log(data[0].year);

Categories

Resources