Reputation: 2674
I have the following JSON object:
[{
"id": 31,
"name": "Foosie",
"terms": [{
"term": 24,
"monthly": 190.09
},
{
"term": 27,
"monthly": 179.6
},
{
"term": 30,
"monthly": 178.78
},
{
"term": 33,
"monthly": 178.06
},
{
"term": 36,
"monthly": 171.11
},
{
"term": 39,
"monthly": 215.36
}
]
},
{
"id": 35,
"name": "Barrie",
"terms": [{
"term": 24,
"monthly": 199.61
},
{
"term": 27,
"monthly": 188.05
},
{
"term": 30,
"monthly": 186.37
},
{
"term": 33,
"monthly": 184.95
},
{
"term": 36,
"monthly": 177.41
},
{
"term": 39,
"monthly": 220.85
}
]
},
{
"id": 23,
"name": "Boosie",
"terms": [{
"term": 24,
"monthly": 290.04
},
{
"term": 27,
"monthly": 287.01
},
{
"term": 36,
"monthly": 257.07
},
{
"term": 39,
"monthly": 245.85
},
{
"term": 42,
"monthly": 241.45
}
]
}
]
I am trying to create a table with both vertical and horizontal tables. (Vertical = names [Boosie, Foosie, Barrie], Horizontal = terms [24,27,...]
Monthly is a button <button (click)="selectPayment(id, term)"></button>
which passes the id and term of the selected cell.
jsfiddle for demo: https://jsfiddle.net/34k8ytrk/
[NOTE: this was done with a <table></table>
for quick demo purposes, your response doesn't have to be a table]
I know that I need to keep track of both name and term, as monthly depends on them, however I am trapped in a hell and am having trouble figuring it out. I understand that I might have to do some manipulation to the data in order to make this work. Any help would be appreciated.
Upvotes: 0
Views: 2326
Reputation: 9146
table.component.html
<table>
<thead>
<tr>
<td>(blank)</td>
<!-- assuming all terms are the same, just take the first of the object -->
<td *ngFor="let head of uniqueHeaders">{{head}}</td>
</tr>
</thead>
<tbody>
<tr *ngFor="let bank of banks; let i = index">
<td>{{bank.name}}</td>
<td *ngFor="let head of uniqueHeaders">{{getColumnData(head, i)}}</td>
</tr>
</tbody>
</table>
table.component.ts
class BankDatabase {
banks: BankData[] // your bank data
get uniqueHeaders(): number[] {
// We want a unique array of numbers for the header
let _uniqueHeader = []
this.banks.forEach((bank) => {
bank.terms.forEach((term) => {
// Append the term if it has not been added yet
if (!_uniqueHeader.includes(term.term))
_uniqueHeader.push(term.term)
})
})
// This should return a unique array of all terms combined
return _uniqueHeader
}
// head is the currently iterated column
// i is the index of the bank (in your example 0 - 2)
getColumnData(head, i): string {
const matchingData = this.banks[i].terms.find(_term => _term.term === head)
// If matching data found, return it's monthly value, else return empty string
return matchingData && matchingData.monthly || ''
}
}
Is this what you want? banks
is the json
data you have.
NOTE that I am using a getter function to flatten the headers array, this is sloppy, you should optimize by saving the flattened data into a property instead and get it from there whenever you need it. You may also need to take an extra step to sort the array as in my example, the array happens to be sorted from the sample data given.
Upvotes: 1