0

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"
    class="mat-elevation-z8"
    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);
    });
  }
1

2 Answers 2

2

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;
  })
);

Stackblitz

Sign up to request clarification or add additional context in comments.

3 Comments

hi thank you, but I also wnt to have a seperate list for categoryId = 3 and 4. How can I do that?
@RocketMonkey do you need records to be displayed in grouped format on mat-table?
my main goal is that actually yes, I want t o group items by categoryId but, angular material tqable doesn't really support grouping so, I decided to go with having multiple tables.
0

You can use function as data source argument

<table mat-table [dataSource]="fetch(2) | async" class="mat-elevation-z8" 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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.