skip to Main Content

I have three components one is the main one and other two are tabs, problem is that matSort is not working, here is my code. have tried few hours searching on several sources but could not make it, any help would be appreciatable.

approve-home.component.ts

    @Component({
      selector: 'app-approve-home',
      templateUrl: './approve-home.component.html',
      styleUrls: ['./approve-home.component.css']
    })
    export class ApproveHomeComponent implements OnInit {

      @ViewChild('tabGroup', {static: false}) tabGroup: MatTabGroup;

      constructor() {
      }

      ngOnInit() {
      }

      onMoveTab(event: { tabIndex: number }) {
        this.tabGroup.selectedIndex = event.tabIndex;
      }

    }

approve-home.component.html

    <mat-tab-group #tabGroup class="tab-hide">
          <mat-tab label="To be hidden">
            <app-approve-main (moveTab)="onMoveTab($event)"></app-approve-main>
          </mat-tab>
          <mat-tab label="To be hidden">
            <app-approve-group (moveTab)="onMoveTab($event)"></app-approve-group>
          </mat-tab>
        </mat-tab-group>```

approve-group.component.ts(this is the 2nd tab which starts once a button is clicked which place in 1st tab

    displayedColumns: string[] = ['applicationNo', 'surname', 'otherNames', 'dob', 'tdType',      'previousTDNo', 'action'];
      dataSource = new MatTableDataSource<TdApplication>([]);

      @ViewChild(MatSort, {static: true}) sort: MatSort;
      @ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
      @Output() moveTab = new EventEmitter<{ tabIndex: number }>();
ngAfterViewInit(): void {
    this.dataSource.sortingDataAccessor = (tdApps, property) => {
      switch (property) {
        case 'applicationNo':
          console.log(property);
          return tdApps.applicationNo ? tdApps.applicationNo.toLocaleLowerCase() : '';
        case 'surname':
          return tdApps.applicantDetails.surname.toLocaleLowerCase();
        case 'otherNames':
          return tdApps.applicantDetails.otherName.toLocaleLowerCase();
        case 'dob':
          return tdApps.applicantDetails.dob.toString();
        case 'tdType':
          return tdApps.applicantDetails.tdType && tdApps.applicantDetails.tdType.documentType ?      tdApps.applicantDetails.tdType.documentType.name.toLocaleLowerCase() : '';
        case 'previousTDNo':
          return tdApps.applicantDetails.prevTdNo && tdApps.applicantDetails.prevTdNo.length > 0 tdApps.applicantDetails.prevTdNo.toLocaleLowerCase() : '';
        default:
          // @ts-ignore
          return tdApps[property];
      }
    };
    this.dataSource.sort = this.sort;

  }

approve-group.component.html

<table mat-table [dataSource]="dataSource"  class="mat-elevation-z8" matSort>

            <!-- Application No Column -->
            <ng-container matColumnDef="applicationNo">
              <th mat-header-cell *matHeaderCellDef mat-sort-header> Application No </th>
              <td mat-cell *matCellDef="let element"> {{element?.applicationNo}} </td>
            </ng-container>

Note: Imports are all correctly implemented

I want to make this sorting function work, i have checked that when i click matSortHeader, ngAfterViewOnInit is not called.instead its called at the very first time when i start this component, which means even before clicking the button in he 1st tab.

2

Answers


  1. Chosen as BEST ANSWER

    Instead of just putting this:

    @ViewChild(MatSort, {static: true}) sort: MatSort;
    

    replace it with this:

    @ViewChild(MatSort) set matSort(sort:MatSort){
    this.dataSource.sort = sort;
    

    }


  2. Mat-tab sets the visibility: hidden CSS property on the hidden tabs.

    So technically, all the components are loaded in the DOM. That’s why the ngAfterViewInit lifecycle gets initiated for all the components, including app-approve-group.

    One way to resolve this is when the tabIndex is the tabIndex of the app-approve-group, then do the sorting in the parent component and pass the sorted data into the child (pp-approve-group) component in an input bound variable. Note that you will have to spread the object so that angular’s ngOnChanges will pick it up.

    OR

    Send the index as an input bound variable and check in the ngOnChanges of that variable if the current tab is the tab index of the child component.

    Basically, you will have to intimate the child component of the tab change and then based on that trigger do the required actions.

    Hope this helps.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search