I have an input in my reactive form which uses the currency pipe. When I reset the form to its initial values, without having changed this price value, it loses the format.
If I've changed the currency value previously, the update gets done correctly.
It seems that Angular checks just the value of the input and not the view that is showing. I mean, if my price is 15, and it is shown as 15,00 €, when I do the reset, the initial value is 15, it hasn’t change. Angular alters the value but not how it should be presented. It seems Angular checks if 15 === 15 and given that this is true, it doesn’t apply the pipe format (even making the pipe impure).
So my workaround is to check if the price value has changed before making the reset. If it has, I can proceed with no problems. But if it hasn't, I need to use patchValue, without the price.
This is my reset method: (I got rid of the comments because they were in Spanish)
reset(): void {
if (this.clientDataForm.getRawValue().contract.price === this.initialValues.contract.price) {
const values = JSON.parse(JSON.stringify(this.initialValues));
delete values.contract.price;
this.clientDataForm.patchValue(values);
this.clientDataForm.markAsPristine();
} else {
this.clientDataForm.reset(this.initialValues);
}
}
I would like to know if this is the correct way to handle pipes with reactive forms. I have tried to use the pipe directly in my component, but it doesn’t seem right to me due to it modifies the value, inserting a format in it.
Maybe is relevant (although I don’t think so), but I’m not using CurrencyPipe directly in my template. I use a custom dynamicPipe which calls the currencyPipe so my input component can be reused. I had a problem with this too because I could not get the pipes from an Injector. At least I couldn’t figure out the way to do it. So, I had to use an ugly switch to call the correct pipe. If someone can point me in the right direction to do this, I would be very grateful.
My dynamicPipe:
import { Pipe, PipeTransform } from '@angular/core';
import { CurrencyPipe } from '@angular/common';
@Pipe({
name: 'dynamicPipe',
})
export class DynamicPipe implements PipeTransform {
public constructor(private currency: CurrencyPipe) { }
transform(value: any, pipeToken: string, pipeArgs: any[]): any {
if (!pipeToken) {
return value;
} else {
let pipe;
// I have tried with the Injector but didn’t work
switch (pipeToken) {
case 'currency':
pipe = this.currency;
break;
}
return pipe.transform(value, ...pipeArgs);
}
}
}
My input component html
<ng-container>
<mat-form-field class="seni-input-container" appearance="standard" floatLabel="always">
<mat-label>{{ text.label }}</mat-label>
<input
matInput
[type]="type ? type : 'text'"
[formControl]="controlContainer.control.controls[controlName]"
[value]="pipe ?
(controlContainer.control.controls[controlName].value | dynamicPipe:pipe.token:pipe.args) :
controlContainer.control.controls[controlName].value"
[placeholder]="text.placeholder"
[required]="hasRequiredField(controlContainer.control.controls[controlName])"
[readonly]="readonly">
<mat-error *ngIf="controlContainer.control.controls[controlName].errors">
{{ utils.currentError(controlContainer.control.controls[controlName]) }}
</mat-error>
<mat-hint *ngIf="text.hint">{{ text.hint }}</mat-hint>
</mat-form-field>
</ng-container>