devsf2020
devsf2020

Reputation: 69

angular 8 , Cannot read property 'sortChange' of undefined

I use angular 8 in my front application but I have this error :

Cannot read property 'sortChange' of undefined

I try add pagination in my datatable(pagination for communication with server)

code component:

        // Angular
    import { Component, ElementRef, OnInit, ViewEncapsulation, ViewChild, AfterViewInit } from '@angular/core';
    import { MatPaginator, MatSort } from '@angular/material';
    import { MatTableDataSource } from '@angular/material/table';
    import { PartnerService } from '../../../../core/partner/services/partner.service';
    import { PartnerDataSource } from '../../../../core/partner/services/partner.datasource.service';
    import { merge, Subscription } from 'rxjs';
    import { tap } from 'rxjs/operators';
    import { SelectionModel } from '@angular/cdk/collections';


    @Component({
        selector: 'kt-partner-list',
        templateUrl: './partner-list.component.html',
        encapsulation: ViewEncapsulation.None
    })
    export class PartnerListComponent implements AfterViewInit, OnInit {

        title = 'mte-test';
        displayedColumns = ['label', 'email', 'personalPhone', 'nature', 'type', 'organization'];
        @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
        @ViewChild(MatSort,{static: false}) sort: MatSort;  
        dataSource:  PartnerDataSource;
        @ViewChild('input',{static: true}) input: ElementRef;
        selection = new SelectionModel<Element>(true, []);
        listPartners: Element[] = [];


        /**
         * 
         * @param partnerService: PartnerService 
         */
        constructor(
            private partnerService: PartnerService
        ){}

        ngOnInit(): void {
            this.dataSource = new PartnerDataSource(this.partnerService);       
            this.dataSource.loadPartners(1);
                
        }

        ngAfterViewInit(){  
                this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
                
                merge(this.sort.sortChange, this.paginator.page)
                .pipe(
                    tap(() => {
                        this.loadPartnerList();
                    }
                    )
                )
                .subscribe();
        }

        loadPartnerList() {
            this.dataSource.loadPartners(this.paginator.pageIndex);
        }
    }
    export interface Element {
        label: string;
        email: string;
        personalPhone: string;
        nature: string;
        type: string;
        organization: string;
    }

code html:

        <div class=" mat-table__wrapper">
                <mat-table class="lmat-elevation-z8" matTableExporter [dataSource]="dataSource" 
                matSort>
                    <ng-container matColumnDef="select">
                        <mat-header-cell *matHeaderCellDef class="mat-column-checkbox">
                            <mat-checkbox (change)="$event " [indeterminate]="selection.hasValue() && !isAllSelected()">
                            </mat-checkbox>
                        </mat-header-cell>
                        <mat-cell *matCellDef="let element" class="mat-column-checkbox" (click)="$event" (change)="$event">
                            <mat-checkbox>
                            </mat-checkbox>
                        </mat-cell>
                    </ng-container>                
                    <ng-container matColumnDef="label">
                        <mat-header-cell *matHeaderCellDef> {{ 'PARTNER.RAISON_SOCIAL' | translate }} </mat-header-cell>
                        <mat-cell *matCellDef="let element"> {{element.label}} </mat-cell>
                    </ng-container>                                                                
                    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
                    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
                </mat-table>            
                <mat-paginator [length]="11" [pageSize]="3"
                    [pageSizeOptions]="[3, 5, 10]"></mat-paginator>
            </div>

when page is loaded I have error sort and also when I click in next page pagination dosen't work

Upvotes: 3

Views: 8512

Answers (2)

GeoffreyMahugu
GeoffreyMahugu

Reputation: 431

This issue is as a result of missing MatSortModule module. To import the module:

In app.module.ts (or shared-module)

import { MatSortModule } from '@angular/material';

@NgModule({
    imports: [ 
       MatSortModule
    ]
})

Upvotes: 9

devsf2020
devsf2020

Reputation: 69

code PartnerDataSource:

        import {CollectionViewer, DataSource} from "@angular/cdk/collections";
    import { MatTableDataSource } from '@angular/material';
    import {Observable, BehaviorSubject, of} from "rxjs";
    import {PartnerService} from "./partner.service";
    import {catchError, finalize} from "rxjs/operators";

    export class PartnerDataSource implements DataSource<Element> {

        private paetnersSubject = new BehaviorSubject<Element[]>([]);

        private loadingSubject = new BehaviorSubject<boolean>(false);

        public loading$ = this.loadingSubject.asObservable();

        constructor(private partnerService: PartnerService) {}

        loadPartners(pageIndex:number) {

            this.loadingSubject.next(true);

        this.partnerService.getAllPartners(pageIndex).pipe(
                    catchError(() => of([])),
                    finalize(() => this.loadingSubject.next(false))
                )
                .subscribe(elements => {
                    this.paetnersSubject.next(elements['hydra:member']);                
                });

        }

        connect(collectionViewer: CollectionViewer): Observable<Element[]> {
            console.log("Connecting data source");
            return this.paetnersSubject.asObservable();
        }

        disconnect(collectionViewer: CollectionViewer): void {
            this.paetnersSubject.complete();
            this.loadingSubject.complete();
        }

    }

    export interface Element {
        label: string;
        email: string;
        personalPhone: string;
        nature: string;
        type: string;
        organization: string;
    }

Upvotes: -1

Related Questions