I've an HTML INPUT field.
<input
[(ngModel)]="item.value"
name="inputField"
type="text"
/>
and I want to format its value and use an existing pipe:
....
[(ngModel)]="item.value | useMyPipeToFormatThatValue"
....
and get the error message:
Cannot have a pipe in an action expression
How can I use pipes in this context?
This question is related to
angular
pipe
html-input
angular2-ngmodel
I tried the solutions above yet the value that goes to the model were the formatted value then returning and giving me currencyPipe errors. So i had to
[ngModel]="transfer.amount | currency:'USD':true"
(blur)="addToAmount($event.target.value)"
(keypress)="validateOnlyNumbers($event)"
And on the function of addToAmount -> change on blur cause the ngModelChange was giving me cursor issues.
removeCurrencyPipeFormat(formatedNumber){
return formatedNumber.replace(/[$,]/g,"")
}
And removing the other non numeric values.
validateOnlyNumbers(evt) {
var theEvent = evt || window.event;
var key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode( key );
var regex = /[0-9]|\./;
if( !regex.test(key) ) {
theEvent.returnValue = false;
if(theEvent.preventDefault) theEvent.preventDefault();
}
My Solution is given below here searchDetail is an object..
<p-calendar [ngModel]="searchDetail.queryDate | date:'MM/dd/yyyy'" (ngModelChange)="searchDetail.queryDate=$event" [showIcon]="true" required name="queryDate" placeholder="Enter the Query Date"></p-calendar>
<input id="float-input" type="text" size="30" pInputText [ngModel]="searchDetail.systems | json" (ngModelChange)="searchDetail.systems=$event" required='true' name="systems"
placeholder="Enter the Systems">
<input [ngModel]="item.value | useMyPipeToFormatThatValue"
(ngModelChange)="item.value=$event" name="inputField" type="text" />
The solution here is to split the binding into a one-way binding and an event binding - which the syntax [(ngModel)]
actually encompasses. []
is one-way binding syntax and ()
is event binding syntax. When used together - [()]
Angular recognizes this as shorthand and wires up a two-way binding in the form of a one-way binding and an event binding to a component object value.
The reason you cannot use [()]
with a pipe is that pipes work only with one-way bindings. Therefore you must split out the pipe to only operate on the one-way binding and handle the event separately.
See Angular Template Syntax for more info.
you must use [ngModel] instead of two way model binding with [(ngModel)]. then use manual change event with (ngModelChange). this is public rule for all two way input in components.
because pipe on event emitter is wrong.
<input [ngModel]="item.value | currency" (ngModelChange)="item.value=$event"
name="name" type="text" />
I would like to add one more point to the accepted answer.
If the type of your input control is not text the pipe will not work.
Keep it in mind and save your time.
because of two way binding, To prevent error of:
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was
checked.
you can call a function to change model like this:
<input [ngModel]="item.value"
(ngModelChange)="getNewValue($event)" name="inputField" type="text" />
import { UseMyPipeToFormatThatValuePipe } from './path';
constructor({
private UseMyPipeToFormatThatValue: UseMyPipeToFormatThatValuePipe,
})
getNewValue(ev: any): any {
item.value= this.useMyPipeToFormatThatValue.transform(ev);
}
it'll be good if there is a better solution to prevent this error.
Source: Stackoverflow.com