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?

1 Answer 1

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

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

3 Comments

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.
See the documentation developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…. I think that the second option is more performant but the speed difference is almost imperceptible
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 <input> always produces a string, so the + operator is needed to convert string to number.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.