1

I´m having problem displaying data inside the table which has column and row headers. I´m trying to make it dynamic by using *ngFor. Can you suggest how to handle *ngFor in this case?

Ts file with data:

export class NewScreen {
  rows = [
    'Name',
    'Surname',
    'Subjects',
    'Grade',
  ];

  data = [
    {
      student: 'Student 1',
      name: 'Alex',
      surname: 'Smith',
      subjects: ['Math','Geometry'],
      grade: ['A','B'],
    },
    {
      student: 'Student 2',
      name: 'Michael',
      surname: 'Laurent',
      subjects: ['Math','Geometry'],
      grade: ['B','C'],
    },
    {
      student: 'Student 3',
      name: 'Sophie',
      surname: 'Miller',
      subjects: ['Math','Geometry'],
      grade: ['A','A'],
    },
  ];
}

HTML: I have been trying to find solution to put inside {{???}} which would result in displaying following table structure, but with no luck:enter image description here

<table>
  <thead>
     <tr>
        <th></th>
        <th *ngFor="let column of data">{{ column.student }}</th>
     </tr>
  </thead>
  <tbody>
     <tr *ngFor="let row of rows">
         <th>{{ row }}</th>
         <td *ngFor="let value of data | keyvalue">{{ value.value[i + 1] }}</td>
     </tr>
  </tbody>
</table>
4
  • Have you heard of the KeyValue pipe. angular.io/api/common/KeyValuePipe Commented Feb 21, 2022 at 16:54
  • It allows the use of both the key and value of a object. Commented Feb 21, 2022 at 16:55
  • Hi Dahir. I have edited the code based on your suggestion, but the data in the table is not being displayed. Is my edited code above correct? Commented Feb 21, 2022 at 17:05
  • If I put {{ item.value }} only, it is displayed like this: [object Object] for each field Commented Feb 21, 2022 at 17:07

1 Answer 1

3

I created a simple example from the HTML and data you provided https://stackblitz.com/edit/angular-vuzjyk

The reason {{ item.value }} shows [object Object] is because you didn't give it an identifier to pick the property of that object you wish to display.

To simplify, I updated your rows[] to match the keys of your data to use it directly.

  rows = ['name', 'surname', 'subjects', 'grade'];

In the HTML I simply use that row to identify the property we wish to display. Also in <th> I capitalize the first alphabet of each header.

   <tr *ngFor="let row of rows">
       <th>{{ row.charAt(0).toUpperCase() + row.slice(1) }}</th>
       <td *ngFor="let item of data">
           {{ item[row] }} 
       </td>
   </tr>

Check out the stackblitz link I gave above, if you have any queries feel free to ask.

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

4 Comments

This looks amazing! Thank you very much. :)
Maybe just 1 additional question - How would I manage matching identifier in case I have 2 words identifier, say First name?
if the identifier comes as First name in the data, you can simple add rows = ['name', 'surname', 'subjects', 'grade', 'First Name']; in your rows list, or that wasn't your question ?
For the attribute name inside the object of data array, I can only use camel case so then it wouldn't match with First Name, but I solved it with the custom pipe :)

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.