1

In this template:

<label for="condition">Condition</label>
<input type="range" min="0" max="4" name="condition"
        [(ngModel)]="vehicle.condition">
<span>{{vehicle.condition | condition}}</span>

I'm interpolating the numeric output of the range slider through a custom pipe which is supposed to convert the numeric value into a human-readable string:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'condition',
  pure: false
})
export class ConditionPipe implements PipeTransform {

  transform(value: number): any {
    switch (value) {
      case 0: return 'Damaged';
      case 1: return 'Rough';
      case 2: return 'Average';
      case 3: return 'Clean';
      case 4: return 'Outstanding';
    }

  }

}

With this pipe, I get the proper output only for the initial value of vehicle.condition. As soon as I update the model (by dragging the slider), the interpolation disappears. Removing the pipe from the interpolated expression works as expected, I see the numerical value update on change.

I get the same result if I put this switch in a class method or component method:

<label for="condition">Condition</label>
<input type="range" min="0" max="4" name="condition"
       [(ngModel)]="vehicle.condition">
<p>numeric: {{vehicle.condition}}</p>
<p>pipe: {{vehicle.condition | condition}}</p>
<p>class method: {{vehicle.niceCondition(vehicle.condition)}}</p>
<p>component method: {{niceCondition(vehicle.condition)}}</p>

Produces:

animation detailing unexpected interpolation behaviour

Why doesn't the interpolation update when processed with this switch statement?

Community
  • 1
  • 1
Benny Powers
  • 5,398
  • 4
  • 32
  • 55

1 Answers1

2

It's because you're trying to compare string variable with number.

Try the following:

transform(value: number): any {
  switch (+value) { <== notice + before of value
    case 0: return 'Damaged';
    case 1: return 'Rough';
    case 2: return 'Average';
    case 3: return 'Clean';
    case 4: return 'Outstanding';
  }
}

Or you can change your pipe like this:

@Pipe({
  name: 'condition',
  pure: false
})
export class ConditionPipe implements PipeTransform {
  result = {
    0: 'Damaged',
    1: 'Rough',
    2: 'Average',
    3: 'Clean',
    4: 'Outstanding'
  }
  transform(value: number): any {
    return this.result[value];
  }
}

Check the plunker

yurzui
  • 205,937
  • 32
  • 433
  • 399
  • Fantastic! Thanks. I'd like to learn more about what the `+` does in the value param, and which of these two options is more performant. If you have a minute I'd appreciate a few pointers. – Benny Powers Jul 25 '16 at 09:35
  • See the documentation https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_plus. I think that the second option is more performant but the speed difference is almost imperceptible – yurzui Jul 25 '16 at 09:39
  • I read that through and at first didn't understand why i needed to convert the condition value to a number. I asked around and learned that `` always produces a string, so the `+` operator is needed to convert string to number. – Benny Powers Jul 25 '16 at 10:46