In my code, I have a JSON list which I fetch a data using fromFetch(). I can get the data and group it on the console by categoryId. I want to display a table of products only with the categoryId of 2. Right now, I can only display a uniform table without the condition I want. What should I do to achieve what I want?
HTML:
<div>
<table
mat-table
[dataSource]="items$ | async"
matSort
>
<ng-container matColumnDef="categoryId">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Category Id</th>
<td mat-cell *matCellDef="let item">{{ item.categoryId }}</td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
<td mat-cell *matCellDef="let item">{{ item.name }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</div>
TS:
items$: Observable<Item[]>;
dataSource: MatTableDataSource<Item>;
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@ViewChild(MatSort, { static: true }) sort: MatSort;
displayedColumns: string[] = ['categoryId', 'name'];
ngAfterViewInit(): void {
this.items$ = fromFetch(
'someitems/data/items.json'
).pipe(
switchMap((response) => {
return response.json();
})
);
this.items$.subscribe(function (result) {
const grouped = _.groupBy(result, (res) => res.categoryId);
this.dataSource = result;
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
console.log(grouped);
});
}
CodePudding user response:
You can extend current items$
observable, to perform further operation using another map
operator. Apply your object transformation logic in map
function.
Update
On the template side you had to add a separate row for groupBy row, right? You can use the when
clause on another mat-row
. Inside when clause you can add isGroup
function, that helps to verify whether to show the groupBy
row or not.
Template
<tr mat-row
*matRowDef="let row; columns: ['initial']; when: isGroup"
></tr>
TS
isGroup(index, item): boolean {
return item.isGroupBy;
}
this.items$ = fromFetch(
'someitems/data/items.json'
).pipe(
switchMap((response) => {
return response.json();
}),
map((data) => {
const grouped = groupBy(data, (res) => res.categoryId);
let output = [];
for (let group in grouped) {
output.push({ initial: group, isGroupBy: true });
output = output.concat(grouped[group]);
}
return output;
})
);
CodePudding user response:
You can use function as data source argument
<table mat-table [dataSource]="fetch(2) | async" matSort>
and the function will look something like:
fetch(catId): MatTableDataSource<Item>{
const data = this.items$.filter(row => row.categoryId === catId);
const ds = new MatTableDataSource<Item>(data);
ds.paginator = this.paginator;
ds.sort = this.sort;
return ds;
}