5

I am looking to add a number pipe to an input field in Angular2. I am using model driven forms and all my inputs have a formControlName instead of using data binding. The problem I have is formControlName="number | number : '1.2-2'" is not valid code.It throws an error saying formControlName cannot be found. I do not want to remove the formControlName in place of a ngModel because I am subscribing to the form inputs to do validation as the form is used.

Hardipsinh Jadeja
  • 1,180
  • 1
  • 13
  • 30
Andrew Anderson
  • 143
  • 1
  • 15
  • 1
    I never tried it but try wrapping it in brackets to it gets evaluated `[formControlName]`. Also formControlName is not a replacement for ngModel. It looks like you are trying to use it as a value holder. That is just for the name of the form control. ngModel can be used alongside formControlName to hold the model value. – Paul Samsotha Oct 19 '16 at 03:40
  • 1
    If you use binding instead of a hardcoded string then you need `[]` or `{{}}` – Günter Zöchbauer Oct 19 '16 at 03:55
  • i alse get this problem you can see this, hope it's helpful. [Angular - Use pipes in services and components](https://stackoverflow.com/questions/35144821/angular-use-pipes-in-services-and-components) – edgex Jan 06 '18 at 01:33
  • Can anyone help, I google searched for an hour but no solution has been found! Thanks in advance! – Haifeng Zhang Mar 13 '18 at 15:13

1 Answers1

1

UPDATE: I realized a simpler, more sensible approach uses valueChanges to perform a setValue with a pipe transform on the change event value.

There are probably some best practices to find about cleaning up subscriptions and being efficient if you have many form controls with subscriptions. You could also clean up any unwanted pipe transformations when you process/submit the final form values.

Basic example (See also: original source):

ngOnInit() {
  this.searchField = new FormControl();
  this.searchField.valueChanges
      .subscribe(val => {
        this.searchField.setValue(myPipe.transform(val))
      });
}

Excerpt with debounce delay + distinctness check:

this.searchField.valueChanges
    .debounceTime(400)
    .distinctUntilChanged()
    .subscribe(term => {
      this.searchField.setValue(myPipe.transform(val))
  });

Original approach...

This answer describes how to create a custom control value accessor for an input field that inserts customized timestamp conversion functions inside the onChange (which gets the convertTo* custom function) and writeValue (which gets the convertFrom custom function) methods.

You would likely create something similar (e.g. adapt template etc. to other form input types) but replace the conversion functions with your desired Pipe transform methods (probably two different types) to achieve what you are after. Angular documentation or source code could be helpful for further details.

Another suggested approach I've seen involved using the pipe during the initial form control creation, but this doesn't seem very useful because it won't continue to apply those changes as the input value is changed by the user. It would display correctly at first but any manipulation would lose the transform filtering and the form would simply be submitted as is without the pipe transform applied.

jmmygoggle
  • 921
  • 7
  • 18