简体   繁体   中英

How can I dynamically create and patch the value of a select field on an Angular reactive form?

I have created an Angular reactive form. I have a select field I am populating dynamically from the values returned from an API call.

I have also been able to patch the value of my form fields.

I am trying to dynamically create a select field and patch the value in the same step.

I have tried various combinations of the creation of the form controls and patchValue to no avail.

The first thing I do is make a call to the API endpoint and handle the returned array object

// The API returns an array of items
elTimecard.timecardDets.forEach((elTimecardDets, i) => {
    // Code dynamically creates the form control fields
    this.addWorkTracked(elTimecardDets);
});

As shown in the aforementioned code, I loop over the returned array to create the form control fields.

// Adds a row of form controls to the form array to track items worked.
// Parameter is optional so that the method can be used to create an empty row of form control fields
addWorkTracked(data?: ITimecardDet): void {
  // Push the new form control fields to the array
  this.timecardDets.push(this.buildWorkTracked(data));
}

I then build the actual form controls

buildWorkTracked(data?: ITimecardDet): FormGroup {
    if (data) {
      // This code should dynamically create the new row of form control
      // fields and set the values based upon the data values passed 
      // through via the API call
      return new FormGroup({
        payCategory: new FormControl(this.buildPayCategories()),
        shiftDifferential: new FormControl(
          this.buildShiftDifferentialCategories()
        ),
        overtimeCategory: new FormControl(this.buildOvertimeCategories()),
        hoursWorked: new FormControl(data.hours),
        earnings: new FormControl({
          value: (this.baseRate * data.hours).toFixed(2),
          disabled: true
        })
      });
    } else {
      // Create a new row of 'clean' form control fields
      return new FormGroup({
        payCategory: new FormControl(this.buildPayCategories()),
        shiftDifferential: new FormControl(
          this.buildShiftDifferentialCategories()
        ),
        overtimeCategory: new FormControl(this.buildOvertimeCategories()),
        hoursWorked: new FormControl('0:00'),
        earnings: new FormControl({ value: null, disabled: true })
      });
    }
  }
// Code that builds the select options
buildPayCategories() {
    this.payCategories = this.timeEntry.payCategories;
    return this.payCategories;
}

Here is the HTML if needed

<select
    matNativeControl
    formControlName="payCategory"
    id="{{ payCategory + i }}">
    <option
        *ngFor="
        let payCategory of payCategories;
        let payCategoryIndex = index"
        [ngValue]="payCategoryIndex">
            {{ payCategory.description }}
    </option>
</select>

I would like the first section of my if clause that receives the data to dynamically create the form control select fields and set the selected value based upon the data value.

For example, if the data returns a 1 and I have four items (with values of 0, 1, 2, 3) in the select dropdown, I want the second item selected since that was what returned from the API call.

I figured out a solution. Feel free to offer a better one. I changed my buildWorkTracked method as follows...

buildWorkTracked(data?: ITimecardDet): FormGroup {
    // If data was provided, dynamically create the form controls stored in const
    // Provide values from data param for inputs
    if (data) {
      const buildTimecardDetsLineItem = new FormGroup({
        payCategory: new FormControl(this.buildPayCategories()),
        shiftDifferential: new FormControl(
          this.buildShiftDifferentialCategories()
        ),
        overtimeCategory: new FormControl(this.buildOvertimeCategories()),
        hoursWorked: new FormControl(data.hours),
        earnings: new FormControl({
          value: (data.baserate * data.hours).toFixed(2),
          disabled: true
        })
      });
      // Patch form array to set selected values based off of data param
      buildTimecardDetsLineItem.patchValue({
        payCategory: data.paycatinc,
        shiftDifferential: data.shiftDifferentialTypeId,
        overtimeCategory: data.overtimeTypeId
      });
      // Return const
      return buildTimecardDetsLineItem;
    } else {
      // If no data provided, create blank form array for end user entry
      return new FormGroup({
        payCategory: new FormControl(this.buildPayCategories()),
        shiftDifferential: new FormControl(
          this.buildShiftDifferentialCategories()
        ),
        overtimeCategory: new FormControl(this.buildOvertimeCategories()),
        hoursWorked: new FormControl('0:00'),
        earnings: new FormControl({ value: null, disabled: true })
      });
    }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM