2

I have a datasource set out like so

[
  {
    "UserId": "00000000-0000-0000-0000-00000000",
    "FullName": "Person one",
    "Houses": [
      {
        "State": "Colorado",
        "City": "Denver",
        "Code": "C_D",
        "Purchased": True
      },
      {
        "State": "Texas",
        "City": "Austin",
        "Code": "A_D",
        "Purchased": True
      },
    ]
  },
 {
    "UserId": "00000000-0000-0000-0000-00000000",
    "FullName": "Person Two",
    "Houses": [
      {
        "State": "Colorado",
        "City": "Denver",
        "Code": "C_D",
        "Purchased": True
      },
      {
        "State": "Texas",
        "City": "Austin",
        "Code": "A_D",
        "Purchased": False
      },
    ]
  }
]

My issue is that I need to have a line for each person, and a column header for each city. Each object of 'Houses' will be the same for each person, but I will not know what the data is, so I can not auto set the matColumnDef.

I am finding that the below

            <table mat-table [dataSource]="dataSource" [trackBy]="myTrackById" fixedLayout recycleRows>

                <ng-container [matColumnDef]="hb.FullName" *ngFor="let hb of HousingBlocks; let i = index">
                    <th mat-header-cell *matHeaderCellDef> Full Name </th>
                    <td mat-cell *matCellDef> {{hb.FullName}} </td>
                </ng-container>
            
                <ng-container [matColumnDef]="eventApproval.UserName" *ngFor="let hb of HousingBlocks; let i = index">
                    <div *ngFor="let house of hb.Houses[i];let i = index">
                        <th mat-header-cell *matHeaderCellDef> 
                            {{house.City}}
                        </th>
                        <td mat-cell *matCellDef> 
                            {{house.Purchased}}
                        </td>
                    </div>
                </ng-container>

            
            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
            <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
        </table>

spits out just the first iteration and doesn't continue with the nested object, example

|Full name |Denver|
|----------|------|
|Person One|True  |
|Person Two|True  |

Where I want

|Full name  |Denver|Austin|
|-----------|------|------|
|Person One |True  |True  |
|Person Two |True  |False |

Any help would be appreciated. I autofill the displayed columns with a foreach loop getting each of the distinct cities so I dont have an id problem, just a populating one.

Thanks.

2
  • what is the value of the class property displayedColumns? Commented May 5, 2022 at 7:00
  • @Benny, the value will be "Full Name", and then a list of the cities that come in from the api Commented May 5, 2022 at 7:59

1 Answer 1

2

See code below and full working example here:

HTML

<table mat-table class="text-list" [dataSource]="dataSource">
    <ng-container *ngFor="let column of displayedColumns; let first = first; let i = index" [matColumnDef]="column">
      <th mat-header-cell *matHeaderCellDef>{{ column }}</th>
      <ng-container *ngIf="first">
        <td mat-cell *matCellDef="let row">{{ row[column] }}</td>
      </ng-container>
      <ng-container *ngIf="!first">
        <td mat-cell *matCellDef="let row">|{{ row.Houses[i-1].Purchased }}</td>
      </ng-container>
    </ng-container>
    <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky:true"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
  </table>

Class

export class AppComponent {
  name = 'Angular ' + VERSION.major;
  data = [
    {
      "UserId": "00000000-0000-0000-0000-00000000",
      "FullName": "Person one",
      "Houses": [
        {
          "State": "Colorado",
          "City": "Denver",
          "Code": "C_D",
          "Purchased": true
        },
        {
          "State": "Texas",
          "City": "Austin",
          "Code": "A_D",
          "Purchased": true
        },
      ]
    },
   {
      "UserId": "00000000-0000-0000-0000-00000000",
      "FullName": "Person Two",
      "Houses": [
        {
          "State": "Colorado",
          "City": "Denver",
          "Code": "C_D",
          "Purchased": true
        },
        {
          "State": "Texas",
          "City": "Austin",
          "Code": "A_D",
          "Purchased": false
        },
      ]
    }
  ];
  displayedColumns = ['FullName', 'Denver', 'Austin'];
  dataSource = new MatTableDataSource<any>([]);

  ngOnInit(): void {
    this.dataSource.data = this.data;
  }
Sign up to request clarification or add additional context in comments.

2 Comments

Ah, I didnt think about putting it all inside one ng-container!
@RayRoyJones I’m glad to hear. It is my pleasure

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.