Issue
I have the following model that reflects the return of an API:
export class IScriptOperationsModel extends Serializable {
public description: string;
public descriptionCode: string;
public scriptOperationOrders: IScriptOperationOrdersModel[];
}
export class IScriptOperationOrdersModel extends Serializable {
public rank: number;
public defaultTime: string;
public asset?: IAssetModel;
public provider?: IProviderModel;
}
export class IProviderModel extends Serializable {
public id: number;
public description: string;
}
export class IAssetModel extends Serializable {
public id: number;
public description: string;
}
my Class
operationModel: IScriptOperationsModel;
formOperation: FormGroup;
providers$: Observable<IResponse<IProviderModel>>;
constructor(private fb: FormBuilder, ...) {}
ngOnInit() {
this.operationModel = new IScriptOperationsModel();
this.operationModel.scriptOperationOrders = [];
this.assetModel = new IAssetModel();
this.providerModel = new IProviderModel();
this.scriptOperationsService
.findScriptOperation(this.operationId)
.subscribe((operation) => {
this.operationModel = operation.data as IScriptOperationsModel;
const scriptOperationOrders = this.formOperation.get('scriptOperationOrders') as FormArray;
this.operationModel.scriptOperationOrders.forEach((values) => {
const createWorkstation = this.createWorkstation();
createWorkstation.reset(values);
scriptOperationOrders.push(createWorkstation); // I populate the scriptOperationOrders
})
this.formOperation.setValue(this.operationModel);
});
}
buildFormOperation() {
this.formOperation = this.fb.group({
descriptionCode: [],
description: [null, Validators.required],
scriptOperationOrders: this.fb.array([])
})
}
createWorkstation(): FormGroup {
return this.fb.group({
rank: this.fb.control(''),
defaultTime: this.fb.control('', Validators.required),
asset: this.fb.group( this.fb.control('')), // doesn't work
provider: this.fb.group( this.fb.control('')) // doesn't work
});
}
get scriptOperationOrders(): FormArray {
return this.formOperation.get('scriptOperationOrders') as FormArray;
}
loadProviders() {
this.providers$ = this.providerService.listProviders();
}
and my Template
<div class="card"
formArrayName="workStations"
*ngFor="let workstation of formOperation.get('scriptOperationOrders')['controls']; index as idx"
>
<div class="card-body" [formGroupName]="idx">
<div class="form-row">
<div class="form-group col-md-1">
<label>Id Oper.</label>
<input type="text" name="idOperation" class="form-control" formControlName="rank"/>
</div>
<div class="form-group col-md-2" formGroupName="provider"> <!-- I think it doesn't work -->
<label>Provider</label>
<select formControlName="id"> <!-- ERROR -->
<option value="">Choose</option>
<option
*ngFor="let prov of (providers$ | async)?.dataArray "
[value]="prov.id">{{ prov.description }}
</option>
</select>
</div>
</div>
</div>
</div>
The form is filled in correctly, however, it gives an error in the console and so I am unable to mark the option with the option coming from the API.
How could I do to select an option on select when accessing the route?
Solution
I will post an answer, with the way I found to solve the problem. Basically I have seven values in the ngOnInit() method, so this way when I access the route provider, the fields that have data will be automatically filled with the respective API data.
What I needed to understand was that there was no need to create a
formGroup
for the asset and provider attributes
// ngOnInit()
this.scriptOperationsService
.findScriptOperation(this.operationId)
.subscribe((operation) => {
this.operationModel = operation.data as IScriptOperationsModel;
this.formOperation.patchValue({
descriptionCode: this.operationModel.descriptionCode,
description: this.operationModel.description,
});
this.operationModel.scriptOperationOrders.forEach(scriptOpOrder => {
(this.formOperation.get('scriptOperationOrders') as FormArray).push(this.fb.group({
rank: scriptOpOrder.rank,
defaultTime: scriptOpOrder.defaultTime,
asset: scriptOpOrder.asset?.id, // Values needed to select the
provider: scriptOpOrder.provider?.id // option based on the id
}))
})
});
this.buildFormOperation();
buildFormOperation() {
this.formOperation = this.fb.group({
descriptionCode: [],
description: [null, Validators.required],
scriptOperationOrders: new FormArray([])
})
}