2

I have a multi-component form that I want to pre-fill with data from an API call. The data populates correctly for every field except for the selected value for the select tag. The value is correct, it is just not displaying the correct option inside of the select. The rest of the form, made of input fields, fill in with the correct data.

The child component takes in a form group and that is what fills in the fields.

I have tried .setValue, .patchValue, [(ngModel)], etc. I cannot get the default value to display correctly. What am I doing wrong?

child-component.html

<select  [attr.id]="reasonCode"  formControlName="reasonCode" placeholder="Reason Code" style="max-width: 100% !important"
                        no-padding selected>
    <option value="" >Please select reason code</option>
    <option *ngFor="let reasonCode of reasonCodesService.reasonCodes">
                        {{reasonCode}}
                    </option>
</select>

child-component.ts

@Input() newReqForm: FormGroup;

parent-component.html

<div *ngFor="let control of newForm.controls['requisitionItem'].controls; let i = index" style="border: 1px solid black; border-radius: 10px; margin-top: 10px;">
    <edit-items (remove)='onRemove($event)'  [newReqForm]="newForm.controls.requisitionItem.controls[i]" style="padding-bottom: 10px"
                    [index]='i'></edit-items>
</div>

parent-component.ts

 ngOnInit() {
    this.employeeService.loadEmployees();
    this.reasonCodesService.loadReasonCodes();
    this.itemReqId = +this.route.snapshot.paramMap.get('ReqId');

    this.reqService.getRequisition(this.itemReqId).subscribe(response => {
        this.editReq = response;
        console.log("EDIT REQ VVV");
        console.log(this.editReq);
        this.editRI = this.editReq.requisitionItem;
        this.newForm = this.fb.group({
            employee: [this.editReq.employee, Validators.required],
            job: [this.editReq.job, Validators.compose([Validators.pattern("^[0-9]+$")])],
            requisitionItem: this.fb.array([

            ])
        });
        this.arrayControl = <FormArray>this.newForm.controls['requisitionItem'];
        this.editRI.forEach(item => {
            let newItem = this.fb.group({
                item: [item.item, Validators.required],
                quantity: [item.quantity, Validators.compose([Validators.required, Validators.pattern("^[0-9]+$")])],
                reasonCode: [item.reasonCode],
                operation: [item.operation],

            })

            this.arrayControl.push(newItem);
            this.setValidators()
        });
        for (let i = 0; i < this.arrayControl.length; i++) {
            this.arrayControl.controls[i].get('reasonCode').setValue(this.editRI[i].reasonCode);
        }
        this.setValidators();
        console.log(this.editReq);
        this.newReqForm = this.newForm;
    });
}

My node/Angular info:

Angular CLI: 6.0.8
Node: 8.11.2
OS: win32 x64

EDIT child-component.ts

isSelected(reasonCode) {
    if (reasonCode == this.rc) {
        return reasonCode
    }        
}
Josh
  • 97
  • 2
  • 11

1 Answers1

0

You are missing a binding on selected of the selected option (see here). You can set the value of the select using reactive forms but this does not actually select an option.

In other words, you need to add something like [selected]="isSelected(reasonCode)" to option:

<option *ngFor="let reasonCode of reasonCodesService.reasonCodes" [selected]="isSelected(reasonCode)">
                    {{reasonCode}}
                </option>

You can implement isSelected for example by comparing its parameter with the value obtained from the FormGroup reference.

FK82
  • 4,907
  • 4
  • 29
  • 42
  • This worked for me. My `isSelected(reasonCode)` is shown in my question now. Is this all I need to do? – Josh Jul 30 '18 at 12:36
  • Basically yes. Full disclosure: I find reactive forms a bit confusing myself. ; ) So there might be a better solution, which I don't know of. Explicitely binding `selected` is my work-around for this situation. Btw, your `isSelected` should ideally return a boolean value. – FK82 Jul 30 '18 at 15:23
  • Reactive forms are definitely confusing and I appreciate your help. But if the `isSelected` returns a boolean, would that actually work? I thought the way i have it would put the correct item in place of the function name. So when you select one, it checks to see if it matches the form control, then it is returned, giving the `[selected]` field a value. i.e. `[selected]="Missing Parts"` – Josh Jul 30 '18 at 16:39
  • @Josh just try and see! I always passed a boolean, but it may actually be overloaded for strings. – FK82 Jul 30 '18 at 19:23