93

Is it possible in Angular 2 to apply a pipe under condition? I would like to do something like:

{{ variable.text | (variable.value ? SomePipe : OtherPipe) }}

If not, what is the preferred way to achieve this effect?

HDJEMAI
  • 8,842
  • 44
  • 66
  • 88
Daniel Kucal
  • 7,692
  • 4
  • 36
  • 59

4 Answers4

206

You need to change the syntax a bit:

{{variable.value ? (variable.text | SomePipe) : (variable.text | pipe2)}}

Plunker example

Günter Zöchbauer
  • 558,509
  • 191
  • 1,911
  • 1,506
8

You could also use ngIf

<ng-container *ngIf="variable.value; else elseBlock">{{ variable.text | SomePipe }}</ng-container>
<ng-template #elseBlock>{{ variable.text | OtherPipe }}</ng-template>

I find it useful in case the line becomes too long.

Random
  • 2,766
  • 1
  • 14
  • 23
ajorquera
  • 1,138
  • 20
  • 25
  • 6
    You can replace the with a so that only the text will be conditional, and no markup will be included in the first case. – Luis Aceituno Aug 06 '19 at 08:46
6

As others pointed out, you can use the syntax of {{condition ? (value | pipe1) : (value2 | pipe2 )}}.

But it is worth knowing that also the format parameter of a pipe can be dynamic. e.g. this is an example of a number which can be formatted with a high precision or a low precision. The condition is passed to a method, which will create a formatter text conditionally.

  // in template
  {{ value | number:getFormat(true) }}

  // in .ts
  public getFormat(highPrecision = false): string {
    const digits = highPrecision ? 3 : 2;
    return `1.${digits}-${digits}`;
  }

So, yes, you can use a condition to select between 2 pipes. But in some cases you may prefer (or only need) to use one pipe with a conditional format parameter..

bvdb
  • 19,466
  • 7
  • 98
  • 111
5

Since such syntax isn't supported, I think that the only way to do that is to implement another pipe to handle the condition:

@Pipe({
  name: 'condition'
})
export class ConditionPipe {
  transform(val,conditions) {
    let condition = conditions[0];
    let conditionValue = conditions[1];

    if (condition===conditionValue) {
      return new Pipe1().transform(val);
    } else {
      return new Pipe2().transform(val);
    }
  }
}

And use it this way:

@Component({
  selector: 'app'
  template: `
    <div>
      {{val | condition:cond:1}}<br/>
    </div>
  `,
  pipes: [ Pipe1, Pipe2, ConditionPipe ]
})
export class App {
  val:string = 'test';
  cond:number = 1;
}

See this plunkr: https://plnkr.co/edit/KPIA5ly515xZk4QZx4lp?p=preview.

Thierry Templier
  • 191,422
  • 38
  • 386
  • 349
  • 3
    It's rather a work-around than an actual solution in this case, but may be useful for more complicated cases, +1 – Daniel Kucal Apr 29 '16 at 12:05
  • Yes you're right! The Günter's solution is better for simple use cases ;-) – Thierry Templier Apr 29 '16 at 12:09
  • I think `Pipe1` and `Pipe2` should be injected in `ConditionPipe`'s constructor instead of making a new one. About more complexe usecases, mine is a condition to use uppercase pipe: `isLabelLowerCase ? (label | translate) : (label | translate | uppercase)` => `label | translateWithCase : isLabelLowerCase`, which sounds great – Random Feb 10 '22 at 09:24