2

I have created a 2 level nested Mat-Table grid in Angular in which it can expand multiple rows at a time. On each row click from the parent grid it calls an API and loads the data for the inner grid.

When I click on the first row, it fetches the data as expected.

First row data

But when I click on the second row, it fetches the data for the second row as expected, but the value of the 1st inner row also becomes the same as the second one. The datasource value of the 1st row is overridden by the second one.

Data of mat-table

I tried making dataSource an array of dataSource[i], using the index, but I was unable to.

I have a working StackBlitz for my issue.

Can anyone help me on this? Thanks in advance.

Roy
  • 7,811
  • 4
  • 24
  • 47
angular_code
  • 319
  • 3
  • 18

2 Answers2

2

The problem is that inner userDatasource is getting overridden everytime you make an api call to get new data for the row.

Here is one of the solution: Whenever you make a call to fetch inner datasource data, assign the data to element

getProjectDetails(element: any) {
    //console.log(element);
    this.tableService.getInnerData(element.Id).subscribe(res => {
      if (res.length == 0) {
        element['innerDatasource'] = new MatTableDataSource();
      } else {
        console.log(res);
        element['innerDatasource'] = new MatTableDataSource(res);
      }
    });
  }

Then in the html, use that value

<table mat-table [dataSource]="element.innerDatasource" multiTemplateDataRows matSort>

Working stackblitz link: https://stackblitz.com/edit/angular-nested-mat-table-triplenested-bpvhfr?file=app%2Ftable-expandable-rows-example.html

Drashti Dobariya
  • 2,455
  • 2
  • 10
  • 23
0

Complementary the answer of Drhasti, another option is allow only show one "detail" at time. In this case, you change the .html to only show one

For this, you can declare a variable "elementExpanded"

elementExpanded:any;

Then you change the *ngIf

<div class="example-element-detail" [@detailExpand]="element==elementExpanded"
       *ngIf="element==elementExpanded">
 ...
</div>

And the (click) in your mat-row

<tr mat-row *matRowDef="let element; columns: columnsToDisplay;"
    [class.example-element-row]="element.addresses?.length" 
    [class.example-expanded-row]="element==elementExpanded"
    (click)="elementExpanded = elementExpanded==element?null:element">
</tr>
Eliseo
  • 50,109
  • 4
  • 29
  • 67