How to use pipes in Angular 5 reactive form input

Dallas Caley picture Dallas Caley · Mar 27, 2018 · Viewed 60.9k times · Source

I am trying to figure out how to use a pipe within a reactive form so that the input is forced into a currency format. I have already created my own pipe for this which I have tested in other areas of the code so I know it works as a simple pipe. My pipe name is 'udpCurrency'

The closest answer I could find on stack overflow was this one: Using Pipes within ngModel on INPUT Elements in Angular2-View However this is not working in my case and I suspect it has something to do with the fact that my form is reactive

Here is all the relevant code:

The Template

<form [formGroup]="myForm" #f="ngForm">
  <input class="form-control col-md-6" 
    formControlName="amount" 
    [ngModel]="f.value.amount | udpCurrency" 
    (ngModelChange)="f.value.amount=$event" 
    placeholder="Amount">
</form>

The component

import { Component, OnInit, HostListener } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

export class MyComponent implements OnInit {
  myForm: FormGroup;

  constructor(
    private builder: FormBuilder
  ) {
    this.myForm = builder.group({
      amount: ['', Validators.required]
    });
  }    
}

The error:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined: '. Current value: 'undefined: undefined'

Answer

AJT82 picture AJT82 · Mar 30, 2018

This is what can happen when you mix template driven form and reactive form. You have two bindings fighting each other. Choose either template driven or reactive form. If you want to go the reactive route, you can use [value] for your pipe...

Note, this pipe is rather only for showing the desired output in the view.

<form [formGroup]="myForm">
  <input 
    [value]="myForm.get('amount').value | udpCurrency"
    formControlName="amount" 
    placeholder="Amount">
</form>