I have this pipe which multiplies the input value by an other value retrieved from a service:
@Pipe({
name: 'multiply'
})
export class MultiplyPipe implements PipeTransform {
constructor(private service: StateService) { }
transform(value: any, args?: any): any {
return value * this.service.multiplier;
}
}
Usage:
{{ value | multiply }}
DEMO
This works fine, but when the multiply
value from the service is changed, it doesn't trigger any change detection, and thus
{{ value | multiply }}
is not run again, leaving the old value on the screen. Any suggestion how this can be fixed?
As discussed in Angular documentation, and as shown in this stackblitz, one way to force the pipe to be called is to make it impure:
@Pipe({
name: 'multiply',
pure: false
})
For more details about pure and impure pipes, you can see this article.
I believe the issue is that while the component receives events if it accesses StateService
, the pipe does not.
To fix this, instead change MultiplyPipe
to take a multiplier
argument, instead of trying to access StateService
:
transform(value: any, multiplier: any): any {
return value * multiplier;
}
Then have hello.component
access StateService
, and pass in the value of multiplier
as an argument to the pipe:
import { Component, Input } from '@angular/core';
import { StateService } from './state.service';
@Component({
selector: 'hello',
template: `<h1>Value = {{value | multiply: this.service.multiplier}}</h1>`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
value = 10;
constructor(private service: StateService) {}
Working example here: DEMO