Search code examples
angularangular-templateangular-pipeangular-template-variable

angular - declare result of pipe as local variable


I'm using ngx-pipe's percentage pipe twice in a label. Once to determine which color class (success or info) and once to display the percentage.

<label class="label" [ngClass]="(item.amount |
percentage:item.total) >= 100 ? 'label-success' : 'label-info'">Progress {{item.amount | percentage:item.total:true}}%</label>

Is there a way that I can store the result of that pipe as a local template variable only once like

<label class="label" #percent="(item.amount |
percentage:item.total)" [ngClass]="percent >= 100 ? 'label-success' : 'label-info'">Progress {{percent}}%</label>

I know you can store it inside an *ngIf or *ngFor directive like

<div *ngIf="item$ | async as item">

or

<div *ngIf="item$ | async; let item">

Is there a similar approach to my issue?


Solution

  • AFAIK it isn't possible write now to alias the calculated binding on runtime(*ngFor with pipe is exception), but what you can do is. Create a function/Pure pipe and apply memoization to that function so that computation will less in amount.

    <label class="label" 
      [ngClass]="getPercentage(item) >= 100 ? 'label-success' : 'label-info'">
         Progress {{getPercentage(item)}}%
    </label>
    

    Component

    calculation: any = {};
    percentage = new PercentPipe();
    // below function can be stay as pure Pipe as well.
    getPercentage (item) {
       let key = `${item.amount}-${item.total}`
       if(!calculate[key]) calculate[key] = percentage.transform(item.amount, item.total, true);
       return calculate[key];
    }
    

    By this solution we were calculating value once and using it elsewhere. But not in template variable, but memoizing last calculated value in component.