I have a form with many fields, It was made with formGroup and formControlName. The problem is when I start the app I need to get the data from the backEnd and display it on the view.
The problem is that the field Funcion is not displaying the value:
Here is a reduced part of my html code:
<form #f="ngForm" [formGroup]="registros" class="fila-contenido">
<div class="campos">
<!-- En Venta THIS IS OK-->
<label>¿En venta?</label>
<mat-radio-group formControlName="enVenta" aria-labelledby="example-radio-group-label"
class="example-radio-group">
<mat-radio-button value="1" class="example-radio-button">Si</mat-radio-button>
<mat-radio-button value="0" class="example-radio-button">No</mat-radio-button>
</mat-radio-group>
</div>
<!-- Activo THIS IS OK-->
<div class="campos">
<label>¿Registrado?</label>
<mat-radio-group formControlName="activo" aria-labelledby="example-radio-group-label"
class="example-radio-group">
<mat-radio-button value="Si" class="example-radio-button">Si</mat-radio-button>
<mat-radio-button value="En Trámite" class="example-radio-button">En Trámite</mat-radio-button>
<mat-radio-button value="No Necesita" class="example-radio-button">No Necesita
</mat-radio-button>
<mat-radio-button value="No" class="example-radio-button">No</mat-radio-button>
</mat-radio-group>
</div>
<!-- Pais THIS IS OK-->
<mat-form-field appearance="">
<mat-label>Pais</mat-label>
<mat-select formControlName="pais">
<mat-option *ngFor="let pais of selectedPaises" [value]="pais">{{pais}}</mat-option>
</mat-select>
</mat-form-field>
<!-- Funcion THIS IS NOT OK-->
<mat-form-field appearance="">
<mat-label style=" font-weight: bold;">Función</mat-label>
<mat-select formControlName="funcion" required (selectionChange)=changeFuncion($event)>
<mat-option *ngFor="let funcion of funciones" [value]="funcion">{{funcion.Funcion}}
</mat-option>
</mat-select>
</mat-form-field>
</form>
And here is the TS code:
ngOnInit(): void {
this.getRegistros();
}
getRegistros() {
this.http.get<Registro>('http://localhost:7000/api/registros/' + this.service.getRow()).subscribe(data => {
data.log = data.log.replace(/\\"/g, '"');
console.log("formateo", JSON.parse(data.log));
let convert = JSON.parse(data.log);
this.registros.controls.enVenta.setValue(convert.enVenta); //this is OK
this.registros.controls.activo.setValue(convert.activo); //this is OK
this.registros.controls.pais.setValue(convert.pais); //this is OK
this.registros.controls.funcion.setValue(convert.funcion); //this is not OK
});
}
What I've tried: I've a write a console.log with all the values of the form, the form has all values included the one that is not displayed.
I think it can be related to the ngOnInit problem. But I tried to put getRegistros()
on ngAfterViewInit
and I was having the same problem :(
Also I tried to use patchValue()
instead of setValue()
but same problem
Do you have any suggestions?
Thanks.
Angular uses object identity to select option. It's possible for the identities of items to change while the data does not. This can happen, for example, if the items are produced from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the second response will produce objects with different identities.
To overcome this issue we have to provide the compareFn function to mat-select using compareWith input that tells Angular how to compare the values.
Try this:
component.html
<mat-form-field appearance="">
<mat-label style=" font-weight: bold;">Función</mat-label>
<mat-select formControlName="funcion" required (selectionChange)=changeFuncion($event) [compareWith]="compareWithFn">
<mat-option *ngFor="let funcion of funciones" [value]="funcion">{{funcion.Funcion}}
</mat-option>
</mat-select>
</mat-form-field>
component.ts
Here i am assuming your funciones object contains id property.
compareWithFn(listOfItems,selectedItem){
return listOfItems && selectedItem && listOfItems.id === selectedItem.id; ;
}