'Angular : matSort with ng-content within mat-table

I'm trying to create a reusable mat table component with pagination, sorting and search. the reusable component that I made displays some simple columns , and projects some custom columns depending on the use case through <ng-content></ngcontent>.

the problem is that sorting doesn't work for the custom projected columns through <ng-content></ngcontent>.

I get that I have two matSort instances and the one on the reusable table is the only one registered by the sort header .

is there any solution to make sorting on the custom projected columns works ? or otherwise any other way to use custom columns which would make sorting works on them ?

the reusable table html :

    <table mat-table [dataSource]="data" class="mat-elevation-z8" matSort [matSortActive]="sortActiveColumn" matSortDisableClear>

    <!--- Note that these columns can be defined in any order.
          The actual rendered columns are set as a property on the row definition" -->

    <!-- Id Column -->
    <ng-container [matColumnDef]="column.name" *ngFor="let column of genericColumns">
        <th mat-header-cell *matHeaderCellDef [mat-sort-header]=" column.sortable ? column.name : null "> {{ column.label }} </th>
        <td mat-cell *matCellDef="let item"> {{item[column.name]}} </td>
    </ng-container>

    <ng-content></ng-content>

    <ng-container matColumnDef="actions">
        <th mat-header-cell *matHeaderCellDef mat-sort-header="actions"></th>
        <td mat-cell *matCellDef="let item">
            <div class="flex gap-4">
                <button mat-mini-fab color="primary" class="text-white shadow-none" (click)="showClicked(item)" *ngIf="actions.includes('show')">
                    <mat-icon>open_in_new</mat-icon>
                </button>
                <button mat-mini-fab color="accent" class="text-white shadow-none" (click)="editClicked(item)" *ngIf="actions.includes('edit')">
                    <mat-icon>edit</mat-icon>
                </button>
                <button mat-mini-fab color="warn" class="shadow-none" (click)="deleteClicked(item)" *ngIf="actions.includes('delete')">
                    <mat-icon>delete</mat-icon>
                </button>
            </div>
        </td>
    </ng-container>

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

some custom columns use cases :

    <app-data-table [data]="retours" [total]="totalRetours" [columns]="columns" (dataTableEvent)="datatableEvent($event)" [actions]="['show','edit','delete']" (onDelete)="remove($event)" (onShow)="show($event)" (onEdit)="edit($event)" matSort matSortActive="created_at">
        <ng-container matColumnDef="users.firstname">
            <th mat-header-cell *matHeaderCellDef mat-sort-header="users.firstname">
                Utilisateur </th>
            <td mat-cell *matCellDef="let item"> {{ item.user.full_name }} </td>
        </ng-container>
        <ng-container matColumnDef="clients.firstname">
            <th mat-header-cell *matHeaderCellDef mat-sort-header="clients.firstname">
                Client </th>
            <td mat-cell *matCellDef="let item"> {{ item.client.full_name }} </td>
        </ng-container>
        <ng-container matColumnDef="total">
            <th mat-header-cell *matHeaderCellDef mat-sort-header="total">
                Somme finale </th>
            <td mat-cell *matCellDef="let item"> {{ item.total_ttc | money }} </td>
        </ng-container>
        <ng-container matColumnDef="payment.status">
            <th mat-header-cell *matHeaderCellDef mat-sort-header="payment.status">
                Status du paiement </th>
            <td mat-cell *matCellDef="let item"> {{ item.payment.status }} </td>
        </ng-container>
        <ng-container matColumnDef="created_at">
            <th mat-header-cell *matHeaderCellDef mat-sort-header="created_at">
                Crée à </th>
            <td mat-cell *matCellDef="let item"> {{ item.created_at | momentdate }} </td>
        </ng-container>
    </app-data-table>
<app-data-table [data]="activityTypes" [total]="totalActivityTypes" [columns]="ActivityTypesTableColumns" (dataTableEvent)="datatableEvent($event)" [actions]="['edit','delete']" (onDelete)="remove($event)" (onEdit)="edit($event)" matSort>
    <ng-container matColumnDef="name">
        <th mat-header-cell *matHeaderCellDef mat-sort-header="name"> Nom Type d'activité </th>
        <td mat-cell *matCellDef="let item"> Fr :{{ item.name.fr }} - En : {{ item.name.en }} </td>
    </ng-container>
    <ng-container matColumnDef="color">
        <th mat-header-cell *matHeaderCellDef mat-sort-header="color"> Coleur </th>
        <td mat-cell *matCellDef="let item">
            <div class="w-8 h-8 rounded-full border-black border" [ngStyle]="{'background-color': item.color}"></div>
        </td>
    </ng-container>
    <ng-container matColumnDef="created_at">
        <th mat-header-cell *matHeaderCellDef mat-sort-header="created_at">
            Crée à </th>
        <td mat-cell *matCellDef="let item"> {{ item.created_at | momentdate }} </td>
    </ng-container>
</app-data-table>


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source