I have a select input with an ngFor loop in it to create the options based on colors array.
The behavior i need is to automatically select the first option and to so that angular reactive forms can get its value when the input is created/changed.
So far my form, it looks like this :
<form [formGroup]="stepOneForm">
<label for="modelSelect">Model:</label>
<select id="modelSelect" formControlName="model">
<option value="" selected>Choose...</option>
<option *ngFor="let model of models" [value]="model.code">
{{ model.description }}
</option>
</select>
<!-- The input i am interested in -->
<ng-container *ngIf="stepOneForm.get('model')?.value as code">
<label for="colorSelect">Color:</label>
<select id="colorSelect" formControlName="color" (change)="onColorSelected()" [value]="colors[0].code">
<option *ngFor="let color of colors" [value]="color.code">
{{ color.description }}
</option>
</select>
<img [src]="imagePath" alt="car">
</ng-container>
</form>
And my TS part looks like this :
ngOnInit() {
this.carService.getModels().subscribe(models => {
this.models = models;
});
this.stepOneForm.valueChanges.subscribe(() => {
this.carService.updateStepOneValidity(this.stepOneForm.valid);
const model = this.stepOneForm.get('model')?.value
this.colors = this.models.find(modelObj => modelObj.code === model)?.colors ?? [];
console.log(this.stepOneForm.get('color')?.value) // This returns '' (empty string)
if (model) {
this.carService.updateShoppingCart(this.stepOneForm.value)
}
})
}
When the ng-container content gets displayed, the subscription gets triggered and on the color input I see a color selected by default, but on this line I get an empty string while i should get the value of this option :
console.log(this.stepOneForm.get('color')?.value)
It's only updating the view, but to update color
form control value programmatically when updating model
form control, it has to be done with form methods, from the component, with .setValue/.patchValue
.
So, you could add a listener to the first select, and then update color
form control.
<select id="modelSelect" formControlName="model" (change)="onModelSelected()">
onModelSelected() {
this.stepOneForm.get('color').setValue(this.colors[0]?.code || '');
}
You could do it from the existing valueChanges
by adding {emitEvent: false}
, to prevent infinite loop, but then the colors select wouldn't work, so you need to do it from the first select, i.e. you need extra listener.