I am creating a pipe to convert one currency value to another. I am making HTTP call to convert value.
@Pipe({
name: "currencyConverter"
})
export class CurrencyConverterPipe implements PipeTransform {
transform(value: number, currencyPair: string): number {
let sourceCurrency = currencyPair.split(":")[0];
let destinationCurrency = currencyPair.split(":")[1];
this.currencyConverterService.convert(sourceCurrency, destinationCurrency).subscribe(successData => {
return successData['fiatValue'] * value;
}, errorData => {
console.error(errorData);
})
}
}
In HTML
<p> {{ value | currencyConverter:'BTC:USD'}}</p>
I am unable to see any value in UI. When i make my pipe impure
, Then it works but it is making many HTTP calls to server. Is there any way to make HTTP call without using pure: false
in pipe
I am creating a pipe to convert one currency value to another. I am making HTTP call to convert value.
@Pipe({
name: "currencyConverter"
})
export class CurrencyConverterPipe implements PipeTransform {
transform(value: number, currencyPair: string): number {
let sourceCurrency = currencyPair.split(":")[0];
let destinationCurrency = currencyPair.split(":")[1];
this.currencyConverterService.convert(sourceCurrency, destinationCurrency).subscribe(successData => {
return successData['fiatValue'] * value;
}, errorData => {
console.error(errorData);
})
}
}
In HTML
<p> {{ value | currencyConverter:'BTC:USD'}}</p>
I am unable to see any value in UI. When i make my pipe impure
, Then it works but it is making many HTTP calls to server. Is there any way to make HTTP call without using pure: false
in pipe
- 1 Return the observable and apply the async pipe on trmplate – Jota.Toledo Commented Feb 21, 2018 at 6:56
- @Jota.Toledo A cleaner solution is to extend async, since there's no benefit from using them separately. – Estus Flask Commented Feb 21, 2018 at 7:22
1 Answer
Reset to default 9This pipe isn't pure by design.
In order to not cause multiple requests, it should return same observable that won't do additional requests until input is changed, something like:
@Pipe({
name: "currencyConverter",
pure: false
})
export class CurrencyConverterPipe {
private sourceCurrency;
private destinationCurrency;
private valueSubject = new Subject();
private value$ = this.valueSubject.asObservable().distinctUntilChanged()
.switchMap(value => {
return this.currencyConverter
.convert(sourceCurrency, destinationCurrency))
.map((data) => data * value);
});
constructor(private currencyConverter: ...) {}
transform(value: number, currencyPair: string): number {
this.sourceCurrency = currencyPair.split(":")[0];
this.destinationCurrency = currencyPair.split(":")[1];
this.valueSubject.next(value);
return this.value$;
}
}
Since it is supposed to be used only in conjunction with async
pipe, it makes sense to join them together and extend AsyncPipe
:
@Pipe({
name: "currencyConverterAsync",
pure: false
})
export class CurrencyConverterPipe extends AsyncPipe {
private sourceCurrency;
private destinationCurrency;
private valueSubject = new Subject();
private value$ = this.valueSubject.asObservable().distinctUntilChanged()
.switchMap(value => {
return this.currencyConverter
.convert(sourceCurrency, destinationCurrency))
.map((data) => data * value);
});
constructor(cdRef: ChangeDetectorRef, private currencyConverter: ...) {
super(cdRef);
}
transform(value: number, currencyPair: string): number {
this.sourceCurrency = currencyPair.split(":")[0];
this.destinationCurrency = currencyPair.split(":")[1];
this.valueSubject.next(value);
return super.transform(this.value$);
}
}