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.
1 Answer 1
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.
12 Comments
name and bankName can there be other names? You should really try to make these consistentbank.bankName instead of bank.name. Be consistent :DExplore related questions
See similar questions with these tags.
name1,name2,monthly, please visualize the table with real data you have in the json. This will make it clearer