Reputation: 499
I'm trying to sort my list-component that I've created with angular material.
<div style="width:30%;">
<mat-nav-list matSort (matSortChange)="sortData($event)">
<th mat-sort-header="stuff.name">Name</th>
<mat-list-item *ngFor="let stuff of vehicleDetails">
<button matLine (click)="updateInfo(stuff.id)"> {{ stuff.name }} </button>
<button mat-icon-button id="btn" *ngIf='check(stuff.alarm)' matTooltip="{{stuff.alarm[tooltipIndex(stuff)]?.timestamp}} - {{stuff.alarm[tooltipIndex(stuff)]?.description}}">
<mat-icon>info</mat-icon>
</button>
</mat-list-item>
</mat-nav-list>
</div>
The data displayed in the list is a bunch of vehicle names. It comes from my vehicleDetails which is an array of type VehicleDetail, containing properties such as name, id, etc. Right now I'm trying to sort by name. Im using the following functions when trying to achieve this functionality:
export class VehiclelistComponent implements OnInit, AfterViewChecked
{
vehicleDetails: VehicleDetail[] = [];
sortedVehicleDetails: VehicleDetail[];
sortData(sort: Sort) {
const data = this.vehicleDetails.slice();
if (!sort.active || sort.direction === '') {
this.sortedVehicleDetails = data;
return;
}
this.sortedVehicleDetails = data.sort((a, b) => {
const isAsc = sort.direction === 'asc';
switch (sort.active) {
case 'name':
return this.compare(a.name, b.name, isAsc);
default:
return 0;
}
});
}
compare(a, b, isAsc) {
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}
My ngOnInit and ngAfterViewChecked looks like this
ngOnInit() {
// Init vehicles
this.getVehicleDetails();
}
ngAfterViewChecked() {
this.sortedVehicleDetails = this.vehicleDetails.slice();
}
How can I solve my problem so I can sort by name or any other properties?
Upvotes: 0
Views: 3610
Reputation: 3176
You need to also get the property by which the object array needs to be sorted.
Something like this
sort(value: any[], criteria: SortCriteria): any[] {
if (!value || !criteria)
return value;
let p: string = criteria.property;
let sortFn:(a: any, b: any) => any = (a, b) => {
let value: number = 0;
if (a[p] === undefined) value = -1;
else if (b[p] === undefined) value = 1;
else value = a[p] > b[p] ? 1 : (b[p] > a[p] ? -1 : 0);
return criteria.descending ? (value * -1) : value;
};
value.sort(sortFn);
return value;
}
Where SortCriteria
is,
interface SortCriteria {
property: string;
descending?: boolean;
}
You can also create a pipe so that you can use it directly in a template
Upvotes: 2