How to bind correct s to dynamic columns created based on dynamic arrays?

I get an array of objects from API that contain, among other data, a targets_and_rewards array that can vary with a minimum of one occurence.
I created a material table showing these values, using static columns and dynamic columns based on the maximum length of targets_and_rewards array for each offer.
I need to bind tds correctly based on these dynamic columns.

Here is how it looks like:

app.component.ts

import { Component, OnInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';

const dataReceivedFromAPI = [
  {
    id: 4000,
    name: 'My awesome offer',
    targets_and_rewards: [
      {
        reward: {
          max: 3.6,
          mean: 0.48,
          min: 0.4,
        },
        target: {
          max: 30,
          mean: 3.71,
          min: 3,
        },
      },
      {
        reward: {
          max: 5.7,
          mean: 1.17,
          min: 1,
        },
        target: {
          max: 5.7,
          mean: 5.88,
          min: 5,
        },
      },
      {
        reward: {
          max: 7.5,
          mean: 3.38,
          min: 3.3,
        },
        target: {
          max: 30,
          mean: 13.35,
          min: 13,
        },
      },
    ],
  },
  {
    id: 5000,
    name: 'My awesome second offer',
    targets_and_rewards: [
      {
        reward: {
          max: 3.5,
          mean: 0.55,
          min: 0.3,
        },
        target: {
          max: 35,
          mean: 5.67,
          min: 4,
        },
      },
      {
        reward: {
          max: 6.8,
          mean: 2.12,
          min: 2,
        },
        target: {
          max: 7.9,
          mean: 4.12,
          min: 3,
        },
      },
      {
        reward: {
          max: 8.2,
          mean: 5.24,
          min: 4.87,
        },
        target: {
          max: 32,
          mean: 17.13,
          min: 15.65,
        },
      },
      {
        reward: {
          max: 9,
          mean: 6.66,
          min: 5.87,
        },
        target: {
          max: 50,
          mean: 34.45,
          min: 21.12,
        },
      },
      {
        reward: {
          max: 8.2,
          mean: 5.24,
          min: 4.87,
        },
        target: {
          max: 32,
          mean: 17.13,
          min: 15.65,
        },
      },
    ],
  },
  {
    id: 6000,
    name: 'My awesome third offer',
    targets_and_rewards: [
      {
        reward: {
          max: 6.1,
          mean: 5.54,
          min: 4.13,
        },
        target: {
          max: 100,
          mean: 45.12,
          min: 31.1,
        },
      },
    ],
  },
];

interface Targeting {
  id: number;
  name: string;
  targets_and_rewards: Array<{
    reward: {
      max: number;
      mean: number;
      min: number;
    };
    target: {
      max: number;
      mean: number;
      min: number;
    };
  }>;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  public dataSource: MatTableDataSource<Targeting>;
  public displayedColumns: Array<string> = ['id', 'name'];
  public targetAndRewardColumns: Array<string> = [];

  ngOnInit(): void {
    // API call binding data variable... (here `dataReceivedFromAPI`)
    // Populate columns with static part (basic `displayedColumns`) and dynamic part (`targetAndRewardColumns`)
    this.populateColumns(dataReceivedFromAPI);
    this.dataSource = new MatTableDataSource(dataReceivedFromAPI);
  }

  populateColumns(data: Array<Targeting>): void {
    let maxTargetsAndRewards: number = 0;
    data.map((offer: Targeting) => {
      const targetsAndRewardsLength: number = Object.keys(
        offer.targets_and_rewards
      ).length;
      if (targetsAndRewardsLength > maxTargetsAndRewards) {
        maxTargetsAndRewards = targetsAndRewardsLength;
      }
    });
    for (let i: number = 0; i < maxTargetsAndRewards; i++) {
      this.targetAndRewardColumns.push(
        `Min Target (${i})`,
        `Min Reward (${i})`,
        `Mean Target (${i})`,
        `Mean Reward (${i})`,
        `Max Target (${i})`,
        `Max Reward (${i})`
      );
    }
    this.displayedColumns = [
      ...this.displayedColumns,
      ...this.targetAndRewardColumns,
    ];
  }
}

app.component.html

<table mat-table [dataSource]="dataSource">
  <ng-container matColumnDef="id">
    <th mat-header-cell *matHeaderCellDef>Id</th>
    <td mat-cell *matCellDef="let offer">
      {{ offer.id }}
    </td>
  </ng-container>

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

  <ng-container
    *ngFor="let column of targetAndRewardColumns"
    [matColumnDef]="column"
  >
    <th mat-header-cell *matHeaderCellDef>
      {{ column }}
    </th>
    <!-- How to dynamically bind tds here ? -->
    <!-- Min target (0) should be equal to first offer.targets_and_rewards[0].target.min for example -->
    <td mat-cell *matCellDef="let offer">
      <!-- Just to populate with something by default -->
      {{ offer.targets_and_rewards[0].target.min }}
    </td>
  </ng-container>

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

And here is a stackblitz snippet to make everything more clear.