0

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.

3
  • 1
    Can you edit your quote block to show how you want the table to look with the real data? So instead of using name1, name2, monthly, please visualize the table with real data you have in the json. This will make it clearer Commented May 26, 2017 at 15:42
  • @borislemke I am building one now Commented May 26, 2017 at 15:43
  • @borislemke edited, jsfiddle: jsfiddle.net/34k8ytrk Commented May 26, 2017 at 15:49

1 Answer 1

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.

Plunker

Sign up to request clarification or add additional context in comments.

12 Comments

Please do not simply copy paste this answer, let me know if you don't understand anything. Learn!
@Moshe ok, that's easy. as for name and bankName can there be other names? You should really try to make these consistent
@Moshe I've updated the answer and my plunker. Let me know if I need to explain anything.
@Moshe but do you understand everything we did there?
your plunker is already good, but again, you used bank.bankName instead of bank.name. Be consistent :D
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.