0

Hello I use angular material mat table so to display my data from an api. I use another api so to handle the Categories. I have two models, issues and categories. For the time I display the ID of the category. I need to display the corresponding category name instead of its id.

Any idea?

My models

export class Issue {
  IssueID: string;
  IssueTitle: string;
  IssueContent: string;
  CategoryID: number;
}


export class IssueCategory {
  public CategoryID: number;
  public CategoryName: string;
}

My html

...
  <ng-container matColumnDef="CategoryTitle">
    <mat-header-cell *matHeaderCellDef mat-sort-header>Category</mat-header-cell>
    <mat-cell *matCellDef="let row">{{row.categoryID}}</mat-cell>
  </ng-container>
...

EDIT

My getAllIssues()

CategoryArray: TicketCategory[] = [];

getAllIssues(): void {
this.httpClient.get<Ticket[]>(this.API_URL).subscribe(data => {
this.dataChange.next(data);      

  this.data.map(issue => ({

    category: this.CategoryArray.find(category => category.CategoryID === issue.CategoryID)
  }));
  }
 }

thank you!

touinta
  • 971
  • 3
  • 10
  • 26
  • I would create a combined type where you fill in the category object instead of the id and use that combined type for your table – Alexander May 28 '20 at 07:17

1 Answers1

2

As the simplest approach you can use already combined data as the data source, for example:

// my-component.ts

@Component(...)
export class MyComponent {
  readonly categories: IssueCategory[] = [{
    CategoryID: 1,
    CategoryName: "First Category"
  }, {
    CategoryID: 2,
    CategoryName: "Second Category"
  }];

  readonly issues: Issue[] = [
    {IssueID: "first", IssueTitle: "First Issue", IssueContent: "first issue content", CategoryID: 1},
    {IssueID: "second", IssueTitle: "Second Issue", IssueContent: "second issue content", CategoryID: 2}
  ];

  readonly dataSource = this.issues.map(issue => ({
    title: issue.IssueTitle,
    content: issue.IssueContent,
    category: this.categories.find(category => category.CategoryID === issue.CategoryID)
  }));
}

Or you can create a pipe which transforms a category id to the name. In this case keep in mind that you should include your pipe in the declarations array of an module.

// category-by-id.pipe.ts

@Pipe({
  name: 'categoryById'
})
export class CategoryByIdPipe implements PipeTransform {
  transform(categoryId: number, categories: IssueCategory[]): string {
    const category = categories.find(category => category.CategoryID === categoryId);
    return category ? category.CategoryName : "";
  };
}
<!-- my-component.html -->

...
  <ng-container matColumnDef="category">
    <mat-header-cell *matHeaderCellDef> Category </mat-header-cell>
    <mat-cell *matCellDef="let element"> {{element.CategoryID | categoryById:categories}} </mat-cell>
  </ng-container>
...

StackBlitz with both examples. Hope it helps you.


Here is another example which uses MatTableDataSource

Valeriy Katkov
  • 33,616
  • 20
  • 100
  • 123
  • thank you for your reply @Valerin. I try to fit your code from the first approach. I already have a datasource from where I fill my mat-table from api. How can I add the second one? – touinta May 28 '20 at 10:10
  • @touinta Could you add more details about the problem? Why not replace the first data-source be the updated one? – Valeriy Katkov May 28 '20 at 10:15
  • I need my initial datasource because in there I do a lot of work as filtering, sorting etc...May I try to add your code to that?....its hard but I will give a try.... – touinta May 28 '20 at 10:18
  • @touinta Ok, let me know if you'll have some troubles. – Valeriy Katkov May 28 '20 at 10:29
  • I update my question. I add my service function in which I add some of your code. How can through this call the category name in my component.html? Is that possible? thank you – touinta May 29 '20 at 06:37
  • @touinta I've added another example to the answer which uses `MatTableDataSource`. Hope it helps you. – Valeriy Katkov May 29 '20 at 08:40