Search code examples
javascriptangularrxjsangular-materialangular-reactive-forms

form array inside mat table created inside an observable


i have a parent component : Parent List contains two child components (first-child list , second-child list )

in the second child list component : i have a mat table that receive the data to display as input data so i create the data Source in the ng OnChanges with the instance of Mat Table Data Source), i use the selection Model to handle the selection row (iuse isAllSelected and master Toggle methods ).

i need to pass the selected rows to the first child component , i use service that contains behaviour subject so i next the data by using the set Data methods .

in the first child component i use the form Array inside the mat table and i handle the selection , do a console log of data Source ( you see in console that when i play with the selection one or many or all in the second list component i have like a loop in console and it takes a time to select all or one in the second list component , may be because i create a table inside the subscribe methods )

you can found my stack-blitz contains the code here ,

https://stackblitz.com/edit/stackblitz-starters-frcek7?file=src%2Fapp%2Fparent-list%2Fparent-list.component.html

try to play with select and we can see that takes a few time and loop so many times in console


Solution

  • You have this.setData() in isAllSelected() method. It causes multiple executions of .next of your subject.

    isAllSelected() is triggered on every change detection multiple times in your template

            [checked]="selection.hasValue() && isAllSelected()"
            [indeterminate]="selection.hasValue() && !isAllSelected()"
    

    if you remove this call of this.setData() from isAllSelected you'll see only one console log

    update:

    in your masterToggle you also trigger selection change for each item in table which causes your subject to next for each row.

    You can fix it by replacing

    this.dataSource.data.forEach((row: any) => this.selection.select(row));
    

    into this

    this.selection.select(...this.dataSource.data);
    

    so that it triggers selection change in one go