How to map element to several attributes in mat-table

361 Views Asked by At

Given a specific object, I'd like to show its enum string value, and an icon of a specific color in a mat-table.

For example, I have a data class which has an enum status:

export enum Status {
  Todo = 'Todo',
  InProgress = 'In Progress',
  Done = 'Done'
}

export interface DataItem {
  id: number;
  status: Status;  // that custom enum from above
}

and the end result for a list of items should be something like:

<tr>
  <td>1</td>
  <td><mat-icon class='gray;' title='Todo'> build </mat-icon></td>
</tr>
<tr>
  <td>2</td>
  <td><mat-icon class='yellow;' title='InProgress'> hourglass_empty</mat-icon></td>
</tr>
<tr>
  <td>3</td>
  <td><mat-icon class='green;' title='Todo'>check_circle</mat-icon></td>
</tr>

Specifically, I'd like to set:

  1. The icon color (using a css class or directly),
  2. The icon name (using material icons),
  3. title attribute (using the enum value).

So my approach is basically to create several methods which will return these three attributes for the template:

// in mytable.component.ts

  getIconName(item : DataItem) {
    switch (item.status) {
      case Status.Todo: 
        return "build";
      case Status.InProgress:
        return "hourglass_empty";
      case Status.Done:
        return "check_circle";
    }
  }
  
  getClass(item : DataItem) {
    switch (item.status) {
      case Status.Todo: 
        return "gray";
      case Status.InProgress:
        return "yellow";
      case Status.Done:
        return "green";
    }
  }
  
  getTitle(item : DataItem) {
    switch (item.status) {
      case Status.Todo: 
        return "To Do";
      case Status.InProgress:
        return "In Progress";
      case Status.Done:
        return "Done";
    }
  }

And then just call these methods in the template, sort of:

<mat-cell *matCellDef="let element" 
    title="{{getTitle(element)}}" 
    class="{{getClass(element)}}">
  <mat-icon> {{getIcon(element)}} </mat-icon>
</mat-cell>

But I feel like I am doing something wrong and this should all be done without calling these methods directly.

1

There are 1 best solutions below

0
On

another way

export enum Status {
  Todo = 'Todo',
  InProgress = 'In Progress',
  Done = 'Done'
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  status = Status;

  constructor() {}
}

,

<td>
  <mat-icon
    class="{{item.status == status.Todo ? 'gray' : item.status == status.Done ? 'green' : 'yellow'}}"
    title="{{status.Todo}}">
    {{item.status == status.Todo ? 'build' : item.status == status.Done ? 'check_circle' : 'hourglass_empty'}}
  </mat-icon>
</td>

check title is correct or not because I am not sure you want it as "To Do" or "Todo"

here is StackBlitz, https://stackblitz.com/edit/angular-ivy-qkhtsx