4

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?

4
  • why do you need another way if ng-container will not add extra html ? Commented Nov 9, 2018 at 13:47
  • Well you gave yourself the answer for a template-oriented solution. Otherwise, know that pipes are simply class instances. This means you can create an instance of them in your component's logic. I am redirecting you to one of my previous answers about a similar question about the date pipe : stackoverflow.com/questions/48183677/…. Commented Nov 9, 2018 at 13:47
  • @trichetriche is it possible to use async pipe like in your answer of the date pipe ?? Commented Nov 9, 2018 at 13:56
  • @malbarmawi yes, the source code of the pipe only requires a change detector reference. But I wouldn't use it, myslef, I prefer to use RxJS by hand and reserve my async pipes to my templates ! Commented Nov 9, 2018 at 14:21

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.