I’m prepping backend data for a table and want to get it set in a way so I can map out the table rows. The headers for the table is based on the date range that is used to query the data (always a 6 month spread), which I then compare and do a merge with the data to set up the initial objects, but then I need to compare with another array from the backend to make the row complete.
Here is the headers and data arrays:
const headers = [ "2022-7", "2022-8", "2022-9", "2022-10", "2022-11", "2022-12" ]
const data = [
{
"planDetails": {
"goals": [
{
"title": "Budget",
"frequency": 4
},
{
"title": "clean",
"frequency": 6
}
]
},
"setVisits": [
{
"goals": [
{
"k": "clean",
"v": 2
},
{
"k": "Budget",
"v": 2
}
],
"date": "2022-9"
},
{
"goals": [
{
"k": "clean",
"v": 2
},
{
"k": "Budget",
"v": 2
}
],
"date": "2022-10"
},
{
"goals": [
{
"k": "Budget",
"v": 1
},
{
"k": "clean",
"v": 2
},
],
"date": "2022-8"
}
]
}
]
And then the steps I’ve taken:
const output = data.shift()
console.log(output
)
const newHeader = headers.map(i => new Date(i).toISOString())
/* console.log(newHeader) */
const visits = output.setVisits.map(i => { return {date: new Date(i.date).toISOString(), goals: i.goals}})
/* console.log(visits) */
const result = newHeader.map(item => {
/* console.log(item) */
const info = visits.find(detail => detail.date === item);
/* console.log(info) */
if (info) {
return {
date: item,
goals: info.goals
}
} else {
return {
date: item,
goals: 0
}
}
})
result.sort((a,b) => a.date > b.date)
let finalArr = []
const next = output.planDetails.goals.forEach(i => {
let newObj = {}
/* console.log(i) */
if ( result.find(a => a.goals.k === i.title)) {
newObj = {
goal: i.title,
frequency: i.frequency,
elem1: {
date: a[0].date,
count: a[0].goals.v
},
elem2: {
date: a[1].date,
count: a[1].goals.v
}
}
/* I've only put to the 2nd index of 6 to try and get the proof of concept down before mapping the rest */
} else if (!result.find(a => a.goals.k === i.title)) {
newObj = {
goal: i.title,
frequency: i.frequency,
elems: {
date: a[0].date,
count: 0
}
}
}
finalArr.push(newObj)
})
console.log(finalArr)
Its that last step that is off and javascript makes my head spin. I’m pretty certain theres a simple way to compare the 2 fields of the objects and map that out, providing a 0 if there is no matching field, but I’m getting no where.
My ideal final array would look like:
[
{goal: 'Budget', frequency: 4, elem1: {date: "2022-7", count: 1}, elem2: {date: "2022-8", count: 3}, elem3: {date: "2022-9", count: 0}, etc.}
{goal: 'clean', frequency: 2, elem1: {date: "2022-7", count: 1}, elem2: {date: "2022-8", count: 0}, elem3: {date: "2022-9", count: 2}, etc.}
]
Thanks in advance for any input, here’s a link to the fiddle: https://jsfiddle.net/joznox/rwyL928a/45/
2
Answers
You could first create a lookup table for the frequency of each goal for a particular date using
Array#reduce
. Then, the final result can be created withArray#map
.Another solution may be to shape your data first, taking advantage of object indexes to aggregate the data.
Then once the data is aggregated, shape it for your output.