ngStyle table based on arrays value

Viewed 33

I want to obtain a table like this:

enter image description here

I have 2 objects

  users = [
    { name: 'john', age: '22' },
    { name: 'mike', age: '20' },
    { name: 'dan', age: '12' },
    { name: 'anne', age: '16' },
    { name: 'jenny', age: '42' },
  ]

  names = [
    { name: 'john', color: 'black' },
    { name: 'mike', color: 'black' },
    { name: 'dan', color: 'red' },
    { name: 'anne', color: 'red' },
    { name: 'jenny', color: 'red' },
  ]

If a name from names is in users, I want it's color to be black inside table, if not, I want it to be red.

This is my html:

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let user of users">
            <ng-container *ngFor="let x of names">
                <ng-container *ngIf="x.name == user.name">
                    <td [ngStyle]="{ 'color': names.color }">{{ user.name }}</td>
                    <td [ngStyle]="{ 'color': names.color }">{{ user.age }}</td>
                </ng-container>
            </ng-container>
        </tr>
    </tbody>
</table>

But it's not working properly. You can see a working snippet here

How can I achieve what I want? Thank you for your time!

2 Answers

You have a typo when referencing color. color is a property of the object, not the array you are looping through:

<td [ngStyle]="{ 'color': names.color }">{{ user.name }}</td>
<td [ngStyle]="{ 'color': names.color }">{{ user.age }}</td>

Should be

<td [ngStyle]="{ 'color': x.color }">{{ user.name }}</td>
<td [ngStyle]="{ 'color': x.color }">{{ user.age }}</td>

You can either create a method that retrieves the color based on name (that you put in your component)

getColor(name) {
  return this.names.find(e => e.name === name).color;
} 

and call with

<td [style.color]="getColor(user.name)">{{ user.name }}</td>
<td [style.color]="getColor(user.name)">{{ user.age }}</td>

You don't need your double loop when using it like that, but it still needs to do a lookup loop for every iteration.

Better is to combine the two arrays before and use that

combined = [];


constructor() {
  this.combined = this.users.map(e => Object.assign(e, this.names.find(x => x.name === e.name)))
}

usage

    <tr *ngFor="let user of combined">        
        <td [style.color]="user.color">{{ user.name }}</td>
        <td [style.color]="user.color">{{ user.age }}</td>
    </tr>
Related