0

I am trying to create a table with dynamic columns. So there are 3 columns that are constantly there and rest are dynamically generated. for example

var newCol = ["node1","node2","node3"];

Then I need to have a total of 6 columns in the table.

The table needs to look like :

ID     TS     Node     node1       node2      node3
1      ts1     a
2      ts2     a
3      ts3     b
4      ts4     c
5      ts5     a
6      ts6     b

I have arrays like :

var idArray = ["1","2","3","4","5","6"];
var ts = ["ts1","ts2","ts3","ts4","ts5","ts6"];
var node = ["a","a","b","c","a","b"];

var newCol = ["node1","node2","node3"];

So the logic behind the newCol array is that an API call needs to be made for each element in newCol array and results to be displayed. Right now the api is not ready and I am trying to create the skeleton like the table shown above. API would return the response in the following format

Edit :

However, I also need the need the colArray which would have to be in the table. So for example

 newCol.forEach(node => {
           this.httpClient.get(this.URL1 + node).subscribe(data => {

           add the data into a array (create array of array)

          });
   });

for ex : URL/newCol[0] would return the data for the API would look like :

{
  "totalReqCount": 6,
  "map": {
    "id1": {
      "api": "asd",
      "tID": "id1",
      "processedTimeDuration": "00:00:11"
    },
    "id2": {
      "api": "asdf",
      "tID": "id2",
      "processedTimeDuration": "00:00:38"
    },
    "id3": {
      "api": "asdfg",
      "tID": "id3",
      "processedTimeDuration": "00:00:59"
    },
    "id4": {
      "api": "qwe",
      "tID": "id4",
      "processedTimeDuration": "00:00:25"
    },
    "id5": {
      "api": "qwer",
      "tID": "id5",
      "processedTimeDuration": "00:00:00"
    },
    "id6": {
      "api": "qwerty",
      "tID": "id6",
      "processedTimeDuration": "00:00:02"
    },
}

The problem statement is to how to populate the data for the columns in column array into the table.

Here is the stackblitz example for the same.

https://stackblitz.com/edit/angular-hsmswb?file=app/table-basic-example.html

Can anyone help with the same. Much appreciated Thanks

10
  • Where exactly do u need help? Making an api call? Or filling the table with ur own data? (statically) Commented Aug 5, 2019 at 10:28
  • @sagat Filling the data from the arrays. So, I am able to get the data into the arrays but can't get it to the table. Might be a really naive question, pardon me for that.. I am really new to angular... So I just need to understand how to visualize the table like shown. Commented Aug 5, 2019 at 10:30
  • okay i understand... Commented Aug 5, 2019 at 10:33
  • The way you are using mat-table in your example is not the same approach as a traditional table. Does it HAVE to use mat-table? Commented Aug 5, 2019 at 10:46
  • @AndrewJuniorHoward Not really, this is my first time working with tables and for creation of dynamic column generated table, I started trying the same. I am not bind to use the mat-table, if it can be achieved with any other resource, it would be glad. Commented Aug 5, 2019 at 10:48

3 Answers 3

2

please check working example https://stackblitz.com/edit/angular-hsmswb-kap4ph

Let me know if you have any doubt.

Changes which I did.

table-basic-example.ts

I moved all variables inside class

public idArray = ["1","2","3","4","5","6"];
public ts = ["ts1","ts2","ts3","ts4","ts5","ts6"];
public node = ["a","a","b","c","a","b"];
public newCol = ["node1","node2","node3"];

added dataSource variable public dataSource = [];

changed line displayedColumns: string[] = ['position', 'name', 'weight']; values should be same which we use in <ng-container matColumnDef="position">.

table-basic-example.html

<ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef> idArray </th>
    <td mat-cell *matCellDef="let element"> {{element.id}} </td>
  </ng-container>

  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef> ts </th>
    <td mat-cell *matCellDef="let element"> {{element.ts}} </td>
  </ng-container>

  <ng-container matColumnDef="weight">
    <th mat-header-cell *matHeaderCellDef> node </th>
    <td mat-cell *matCellDef="let element"> {{element.node}} </td>
  </ng-container>
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you so much for your response. However, it provides me answer to half of the problem statement. I have edited the question for better understanding. Can you please take a look at that and let me know the procedure for the same. Much appreciated help.
steps for your updated query. 1. displayedColumns: string[] = ['position', 'name', 'weight', 'node1', 'node2', 'node3']; 2. for (let i = 0; i < this.idArray.length; i++) { this.dataSource.push({ id: this.idArray[i], ts: this.ts[i], node: this.node[i] }); this.newCol.map((val, index) => { this.dataSource[i][val] = this.newColData[index].map[id${this.idArray[i]}]; }) }
you can check updated code on same url - stackblitz.com/edit/angular-hsmswb-kap4ph
Thank you again for answering the same. But the fact being that its not dynamic in nature. What if the colArray has 4 objects instead of 3. So I am looking for a dynamic content generation instead of static one.. I guess something like ngFor in html. Although I am not able to understand how to use that..
the length can be obtained from the colArray itself as I am getting that array via an API itself. Your code has static node1,node2,node3 values which is not what I am looking for. The rest of the implementation is the same... the only thing that I need to figure out is display those columns on html by not pre-defining the columns
|
1

This is the best practise way of doing it. This way, the back end can create as many columns at it wishes to without front end involvement:

https://stackblitz.com/edit/angular-hsmswb-qxwdsa?file=app%2Ftable-basic-example.html

In short your back end code should be structured as follows:

yourData = [
  {
    "columns": [
      {
        "heading": "Name",
        "field": "name"
      },
      {
        "heading": "Age",
        "field": "age"
      },
      {
        "heading": "Address",
        "field": "address"
      },
      {
        "heading": "Telephone Number",
        "field": "telephoneNumber"
      }
    ],
    "data": [
      {
        "name": "Andrew",
        "age": "22",
        "address": "1 Howick Place",
        "telephoneNumber": "6546546546"
      },
      {
        "name": "Simon",
        "age": "32",
        "address": "2 Howick Place",
        "telephoneNumber": "6546546456547"
      },
      {
        "name": "Brian",
        "age": "28",
        "address": "3 Howick Place",
        "telephoneNumber": "6546546456547"
      }

    ]
  }];

Note that the columns.field MUST match the key's used in the data array. This approach is great as you may not be able to use mat-table, so this will work with traditional tables.

Comments

0

I think the best way to tackle this would be to create an array of objects where each object is a row in your table.

array = [
    {
        id: 1,
        TS: ts1,
        Node: a,
        node1: '',
        node2: '',
        node3: '',
    }, {
        id: 2,
        TS: ts2,
        Node: B,
        node1: '',
        node2: '',
        node3: '',
    }
]

Then you can use *ngFor to loop over your <tr></tr>

<tr *ngFor="let row of array">
<td>{{row.id}}</td>
<td>{{row.TS}}</td>
<td>{{row.Node}}</td>
<td>{{row.node1}}</td>
<td>{{row.node2}}</td>
<td>{{row.node3}}</td>
</tr>

Then once you have performed your API calls you can replace the values for node1, node2, node3 etc and the table will update.

8 Comments

Thank you for your answer. Can you please tell me how to actually create this array from multiple arrays. As I see, you are creating the array of JSON objects. I have different arrays for different columns as you can see. Could you elaborate on the same.
for (let i = 0; i < this.idArray.length; i++) { this.dataSource.push({ id: this.idArray[i], ts: this.ts[i], node: this.node[i] }); }
Yes this would work, and then you could simply push blank values for the 3 extra columns if you so wish within the same for loop.
So, the thing is that these 3 extra columns are not specific.. it might be 4 or 5 or more as well. If possible for anyone of you, could you share a demo for the creation of the table. Much appreciated help @Sam Thanks a lot
So how are you determining the number of these extra columns to render? Is this derived from the API response?
|

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.