I have created a function to map over a json data to display it as a table using Angular Material. I would like to
- Display the highest bidamt and the corresponding from my table in my and
- Currently my id is arranged in order of timing (i.e. an earlier entry is displayed as 1, a later entry is displayed as 2 etc.). How can I rearrange it to display it in order from highest to lowest bid?
bid.component.html
<div >
<div >
<span >{{bid.bidamt | max}}</span>
<span >{{bid.name | max}}</span>
</div>
<table mat-table [dataSource]="dataSource"
matSort matSortDisableClear matSortActive="bidamt" matSortDirection="desc">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> No.</th>
<td mat-cell *matCellDef="let bid"> {{bid.id}} </td>
</ng-container>
<ng-container matColumnDef="bidamt">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Bids</th>
<td mat-cell *matCellDef="let bid"> {{bid.bidamt | number}} UCD</td>
</ng-container>
<ng-container matColumnDef="bidname">
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let bid"> {{bid.bidname}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator
style="color: rgba(255,255,255,0.7)"
[pageSize]="2"
[pageSizeOptions]="[2, 5, 10]"
aria-label="Select page">
</mat-paginator>
</div>
bid.json
{
"bids": [
{
"bidamt": 500,
"bidname": "Alice",
"id": 1
},
{
"bidamt": 300,
"bidname": "Ben",
"id": 2
},
{
"bidamt": 2000,
"bidname": "Clare",
"id": 3
}
]
}
bid.component.ts
export class BidComponent implements OnInit, OnDestroy, AfterViewInit {
displayedColumns: string[] = ['id', 'bidamt', 'name'];
dataSource!:MatTableDataSource<any>;
@ViewChild('paginator') paginator! : MatPaginator;
@ViewChild(MatSort) matSort! : MatSort;
subscription: Subscription = new Subscription;
constructor(private BidService: BidService){ }
async ngOnInit() {
this.BidService.getBids().subscribe((response:any) =>{
this.dataSource = new MatTableDataSource(response);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.matSort;
})
}
}
CodePudding user response:
You have two approach:
Sort the array before create the data source
this.dataSource = new MatTableDataSource(response .sort((a,b)=>a.bidamt-b.bidamt));
Create a function like
sortTable(active:string,direction:string) { this.sort.active=active this.sort.direction=direction as SortDirection this.sort.sortChange.emit( {active: active, direction: direction as SortDirection}); }
And call after asign the sort
... this.dataSource.sort = this.matSort; this.sortTable('bidamt','asc')
To know the max and store in a variable. first declare
max:number=0
then, simple use reduce of the array in subscribe
this.BidService.getBids().subscribe((response:any) =>{
this.dataSource = new MatTableDataSource(response);
this.max=response.reduce((a,b)=>b.bidamt>a?b.bidamt:a,-1000)
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.matSort; //<--add this line
})
Then you can use to add a class in the row
<tr mat-row [class.highest-amt-name]="row.bidamt==max"
*matRowDef="let row; columns: displayedColumns;"></tr>
or using style-background
<tr mat-row [style.background-color]="row.bidamt==max?'red':null"
*matRowDef="let row; columns: displayedColumns;"></tr>
If you want to use in a span you simply use
{{max}}
Update we can add a new property "order" (or reemplace the "id" by order) using simply sort and map, e.g.
response=response.sort((a,b)=>a.bidamt-b.bidamt)
.map((x:any,i:number)=>({...x,order:i}))
//or
response=response.sort((a,b)=>a.bidamt-b.bidamt)
.map((x:any,i:number)=>({...x,id:i}))
See how we use the spread operator (the ...
x) to create an object with all the properties of the object and a new property "order" or a change of the property "id")
update 2 if we want to get the "element" with a "bidamt" greater. Using reduce we can do
this.max=response.reduce((a,b)=>b.bidamt>a.bidamt?b:a,response[0])
Well, if we already have the array sorted is simple
reduce[0] //the first element or
reduce[reduce.length-1] //the last element
in this case max is an object, so to compare the row we need use max.bidmat
<tr mat-row [style.background-color]="row.bidamt==max.bidmat?'red':null"
*matRowDef="let row; columns: displayedColumns;"></tr>