Reputation: 446
I am working with Angular Material Table. I want to sort the items with mdSort, but when i start the App the table says that the view child of mdsort is undefined. What is the misatke?
My code is the same as in the example here: material.angular.io
here is the error log:
ERROR TypeError: Cannot read property 'mdSortChange' of undefined
at AliasDataSource.webpackJsonp.../../../../../src/app/admin/admin.component.ts.AliasDataSource.connect (admin.component.ts:106)
at MdTable.webpackJsonp.../../../cdk/@angular/cdk.es5.js.CdkTable._observeRenderChanges (cdk.es5.js:2005)
at MdTable.webpackJsonp.../../../cdk/@angular/cdk.es5.js.CdkTable.ngDoCheck (cdk.es5.js:1970)
at checkAndUpdateDirectiveInline (core.es5.js:10897)
at checkAndUpdateNodeInline (core.es5.js:12382)
at checkAndUpdateNode (core.es5.js:12321)
at debugCheckAndUpdateNode (core.es5.js:13182)
at debugCheckDirectivesFn (core.es5.js:13123)
at Object.eval [as updateDirectives] (AdminComponent.html:27)
at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13108)
my HTML table snipped
<md-table #table [dataSource]="aliasSource" mdSort>
<ng-container cdkColumnDef="aliasId" md-sort-header>
<md-header-cell *cdkHeaderCellDef> Alias</md-header-cell>
<md-cell *cdkCellDef="let a"> {{ a.AliasName }}</md-cell>
</ng-container>
...
</md-table>
the class where he say it's undefined
export class AliasDataSource extends DataSource<any> {
constructor(private _aliasDatabase: AliasDatabase, private _sort: MdSort) {
super();
}
/** Connect function called by the table to retrieve one stream containing
the data to render. */
connect(): Observable<Mailalias[]> {
const displayDataChanges = [
this._aliasDatabase.dataChange,
this._sort.mdSortChange, // here is the point where the exception throws
];
return Observable.merge(...displayDataChanges).map(() => {
return this.getSortedData();
});
}
disconnect() {}
/** Returns a sorted copy of the database data. */
getSortedData(): Mailalias[] {
const data = this._aliasDatabase.data.slice();
if (!this._sort.active || this._sort.direction == '') { return data; }
return data.sort((a, b) => {
let propertyA: number|string = '';
let propertyB: number|string = '';
switch (this._sort.active) {
case 'aliasId': [propertyA, propertyB] = [a.ID, b.ID]; break;
case 'adresse': [propertyA, propertyB] = [a.FromAddr, b.FromAddr]; break;
case 'name': [propertyA, propertyB] = [a.FromName, b.FromName]; break;
}
let valueA = isNaN(+propertyA) ? propertyA : +propertyA;
let valueB = isNaN(+propertyB) ? propertyB : +propertyB;
return (valueA < valueB ? -1 : 1) * (this._sort.direction == 'asc' ? 1 :
-1);
});
}
}
my main class of the TS File
export class AdminComponent implements OnInit {
aliasColumns = ['aliasId', 'adresse', 'name', 'host', 'password', 'port', 'ssl', 'user', 'menu'];
aliasSource: AliasDataSource | null;
@ViewChild(MdSort) sort: MdSort;
alias: Mailalias[];
isLoading = false;
constructor(private ms: MailService, private router: Router) {
}
ngOnInit() {
this.isLoading = true;
console.log(this.sort);
this.ms.getAll().subscribe(res => {
this.alias = res;
const aliasDatabase = new AliasDatabase(res);
this.aliasSource = new AliasDataSource(aliasDatabase, this.sort);
// this.aliasSource = new AliasDataSource(aliasDatabase);
this.isLoading = false;
this.isLoading = false;
const a = AliasFactory.errorObject(res);
if (a.Status === 401) {
this.router.navigate(['/login']);
}
});
}
}
Upvotes: 2
Views: 3531
Reputation: 17038
Add MdSortModule
to your module's list of imports.
If you are defining an NgModule
, and a component of the module uses mdSort
, you'll have to update the NgModule's imports as follows:
@NgModule({
imports:[MdTableModule,
...
MdSortModule
],
...
})
export class ModuleThatImportsMdSortModule{}
Upvotes: 2
Reputation: 39025
I also encountered this. don't forget to add MdSortModule
to you list of imports.
Upvotes: 2
Reputation: 446
So now i found my mistake id had in my div container a ngIf that hide's my table -.-
When someone have the same problem look if you have a ngIf in a tag before !!!
But thanks for the help @Habeeb
Upvotes: 4
Reputation: 1040
In HTML
<table mdSort (mdSortChange)="sortData($event)">
In TS have the implementation and logic. Refer example
Initial value
desserts = [
{name: 'Frozen yogurt', calories: '159', fat: '6', carbs: '24', protein: '4'},
{name: 'Ice cream sandwich', calories: '237', fat: '9', carbs: '37', protein: '4'},
{name: 'Eclair', calories: '262', fat: '16', carbs: '24', protein: '6'},
{name: 'Cupcake', calories: '305', fat: '4', carbs: '67', protein: '4'},
{name: 'Gingerbread', calories: '356', fat: '16', carbs: '49', protein: '4'},
];
const data = this.desserts.slice();
Sorting logic
this.sortedData = data.sort((a, b) => {
let isAsc = sort.direction == 'asc';
switch (sort.active) {
case 'name': return compare(a.name, b.name, isAsc);
case 'calories': return compare(+a.calories, +b.calories, isAsc);
case 'fat': return compare(+a.fat, +b.fat, isAsc);
case 'carbs': return compare(+a.carbs, +b.carbs, isAsc);
case 'protein': return compare(+a.protein, +b.protein, isAsc);
default: return 0;
}
});
implement the below function too
function compare(a, b, isAsc) {
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}
Upvotes: 1