PrimeNG turbo table individual cell manipulation with observable

642 views Asked by At

I'm using the async pipe in my turbo table to show documents from a firestore collection.

One of the fields in the document is called providerName and there instead of saving the actual provider name I'm saving the provider firebase id (nested object). This way whenever the actual provider object changes (edit operation) i will have the correct name in my original document

Currently my primeng p-table is showing the provider id so I've written the following code to manipulate it

Here is the template.html code

<p-table #dt [columns]="cols" [value]="expenseService.expenses$ | async" dataKey="id">
        <ng-template pTemplate="body" let-expense>
          <tr [pSelectableRow]="expense">
            <td *ngFor="let col of cols" [ngSwitch]="col.field">
              <span *ngSwitchCase="'serviceProviderName'">{{getName(expense)}}</span> <--- this is the important line
              <span *ngSwitchCase="'amount'">{{expense.amount | number:'1.0-0'}}</span>
              <span *ngSwitchDefault>{{ expense[col.field] }}</span>

            </td>
          </tr>
        </ng-template>
      </p-table>

and in my component i have the following implementation of the getName()

  getName(event) {
    const label = this.serviceProviders.filter(x => x.value === event.serviceProviderName);
    if (label && label[0]) {
      return label[0].label;
    } else {
      return event.serviceProviderName;
    }
  }

The serviceProviders is empty at the time the table gets rendered as its filled by an observable, so here comes my question.

How do I get the datatable to know that the serviceProviders is ready and then call the getName function?

2

There are 2 answers

2
Suresh Kumar Ariya On BEST ANSWER

Instead of calling the method from HTML Template which does async/firbase call. You can perform that same logic in component using .map/for loop. Final result can be assigned to the HTML.

Also calling async call in HTML template in *ngFor will have a performance impact and it will make UI unresponsive.

0
Jonathan On

You can just call the async before and use the as keyword to declare on non-observable:

<div *ngIf="test | async as t">
  <p-table [value]="t" [resizableColumns]="true" [autoLayout]="true">
  ...
  </p-table>
</div>