<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.2.1/rxjs.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.5.7/core.js"></script>
<script src="https://unpkg.com/@angular/core@6.0.5/bundles/core.umd.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.8.26/zone.min.js"></script>
<script src="https://unpkg.com/@angular/http@6.0.5/bundles/http.umd.js"></script>
<script src="https://unpkg.com/@angular/common@6.0.5/bundles/common.umd.js"></script>
<script src="https://unpkg.com/@angular/router@6.0.5/bundles/router.umd.js"></script>
<script src="https://unpkg.com/@angular/compiler@6.0.5/bundles/compiler.umd.js"></script>
<script src="https://unpkg.com/@angular/platform-browser@6.0.5/bundles/platform-browser.umd.js"></script>
<script src="https://unpkg.com/@angular/platform-browser-dynamic@6.0.5/bundles/platform-browser-dynamic.umd.js"></script>
<script src="https://unpkg.com/@angular/forms@6.0.5/bundles/forms.umd.js"></script>

<my-app></my-app>
// app.js

const { Component, VERSION, Pipe, PipeTransform } = ng.core;

@Pipe({
  name: 'applyPure',
  pure: true // immutable (value) inputs & pure fn (function)
})
class ApplyPurePipe implements PipeTransform {

  transform(value: any, fn: Function): any {
    return fn(value);
  }
}

@Pipe({
  name: 'apply',
  pure: false // any (value) inputs & any fn (function)
})
class ApplyPipe implements PipeTransform {

  transform(value: any, fn: Function): any {
    return fn(value);
  }

}

@Component({
  selector: 'my-app',
  template: `
<div>
<hr/>
<label for="value">Input {{fromScale}}
  <input id="value" [value]="value" type="number" (input)="value = $event.target.value" >
</label>

<button (click)="toggleScale()">Convert to {{toScale}}</button> | 1 kg = 2.204 lbs

<hr/>

<h3>With applyPure Pipe :(</h3>
<h4>Note: with applyPure pipe, the conversion pipe is only applied if input changes, not when only the scale toggles</h4>
<div style="font-size: x-large" [style.color]="(value > (value | applyPure: covertValue)?toScale == 'kg': toScale == 'lbs')?'green':'red'">
  {{value}} {{fromScale}} = {{value | applyPure: covertValue}} {{toScale}}
</div>
<h4>convertValue(input) is <strong>not a pure function </strong>it depends on component.toScale, which it closes over from outside (component.toScale)</h4>
<h4>If use it using <em>applyPure</em> pipe (pure = true), the pipe bindings will not be evaluated when the toScale changes on press of button as it detects input only</h4>
<hr/>

<h3>With apply Pipe :)</h3>
<h4>Note: with apply pipe, the conversion pipe is applied with standard change detection, which detects changes to both, input and the scale</h4>
<div style="font-size: x-large" [style.color]="(value > (value | apply: covertValue)?toScale == 'kg': toScale == 'lbs')?'green':'red'">
  {{value}} {{fromScale}} =  {{value | apply: covertValue}} {{toScale}}
</div>
<h4>We know convertValue(input) is <strong>not a pure function </strong> hence we are using it with apply pipe not <del>applyPure pipe</del></h4>
<h4>The <em>apply</em> pipe (pure = false), the pipe bindings will be evaluated when the toScale changes on press of button as well as on changes to input</h4>

<hr/>
</div>
  `
})
class AppComponent  {

  value = 0;
  fromScale: 'kg' | 'lbs' = 'kg';
  toScale: 'kg' | 'lbs' = 'lbs';
  toggle = false;

  constructor() {}

  toggleScale() {
    this.toggle = !this.toggle;
    this.fromScale = this.toggle ?  'lbs' : 'kg';
    this.toScale = this.toggle ? 'kg' : 'lbs' ;
  }

  covertValue = (number) => {
    return this.toScale === 'kg' ? number / 2.2 : number * 2.204;
  }
  
}

// main.js
const { BrowserModule } = ng.platformBrowser;
const { NgModule } = ng.core;
const { CommonModule } = ng.common;
const { FormsModule } =  ng.forms

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    CommonModule,
  ],
  declarations: [AppComponent, ApplyPipe, ApplyPurePipe],
  bootstrap: [AppComponent],
  providers: []
})
class AppModule {}

const { platformBrowserDynamic } = ng.platformBrowserDynamic; 

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.