5
votes

How to display some text in input FormControl that not equal to value of this FormControl?

For example, get some object from a server - {id: 1, name: "Name1"}, and set value of FormControl to that object or to object.id but display value set to object.name - "Name1".

Why i need it:

I use angular material autocomplete and it set the value of FormControl to object (from selected mat-option) and display value to string via displayWith. I want to repeate this behavior when fetch data from server for some consistency and convenience

4
do you want to keep id as a hidden value?In formcontrol? - umesh99
i want to save object in value of FormControl but show string from this object as angular material autocomplete do it - alarcl

4 Answers

5
votes

I do some research for my question.

It is need to use FormControlDirective and its valueAccessor.writeValue() for set display value of input (it use renderer) or as alternative nativeElement.value.

And FormControl's setValue() with emitModelToViewChange = false for set FormControl value.

In template

<input [formControl]="ctrlF" #ctrlD="ngForm">

In controller

 @ViewChild('ctrlD', {read: FormControlDirective})
 ctrlD :FormControlDirective
 ...
 this.ctrlD.valueAccessor.writeValue("display value")
 this.ctrlD.control.setValue({foo: "foo", bar: "bar"}, {
     emitModelToViewChange: false
 })

planker

0
votes

You can also just use the setValue() twice. First set the control value to the value that you want to display (view). Then set the control value again with the value that you want to save (model), but this time without changing the view, by using {emitModelToViewChange: false}

  this.form?.controls.country.setValue('Value to display')
  this.form?.controls.country.setValue('realValue', {emitModelToViewChange: false});
0
votes

Another aproach is use [ngModel] and (ngModelChange) inside the FormGroup. Remember that the formControl exist always. The idea is simple. Imagine you has a FormGroup

form=new FormGroup({
   control:new FormControl()
})

<form [formGroup]="form">
   <input [ngModel]="form.get('control').value?form.get('control').value.name:''"
       (ngModelChange)="form.get('control').setValue({id:$event})"
       [ngModelOptions]="{standalone:true}">
</form>

But if you're using mat-autocomplete, by defect is asigned to the formControl the object and you can also "initialize" the formControl :(. Is the second example in the docs

0
votes

I've subscribed to the formControl valueChanges observable and validate the value with a condition, and reset it if it needs to:

this.myForm.valueChanges.subscribe( value => {
  if(this.validateFormValue(value)){
    this.myForm.patchValue(this.extractValue(value))
  }
})

validateFormValue(value){
  // if condition
  return true
  // else return false
}

extractValue(value){
  // return the value you want after calculation or extraction
  return value.realValue
}