简体   繁体   中英

Mapping data to a FormArray after the form has been initialised

I am building an Angular Reactive Form. I have an array in my form that allows multiple instances of 3 fields. I have managed to pre-populate the form and these fields. However, I am not happy with populating at the same time as creating the form. I am populating/mapping to the array when the form is being created. Ideally, I want the form to be created first then populate the form afterwards. Reason being is validation checks, changes after view etc...

public createForm() {
this.service.getmodel().subscribe(response => {
  this.model = response;
  this.form = this.fb.group({
    // justificationItems: this.fb.array(
    //   this.model.justificationItems.map(x => 
    //     this.buildJustificationFields(x)
    //   )
    // )
    justificationItems: this.fb.array([
                this.fb.group({
        name: new FormControl(''),
        description: new FormControl(''),
        code: new FormControl(''),
                })
            ])
  });
});
this. populateForm();

}

The commented out code above is the working population code. I have introduced a populateForm() function and also created the input fields on the form as empty initially.

  populateForm() {
        const f = this.form;
        const model = this.model;

        f.get('justificationItems').setValue(model.justificationItems.map(x => this.buildJustificationFields(x)));
        f.updateValueAndValidity();
    }

The population function should look at the this.form that now exists then update the fields according to the this.model if there is data to pre-populate of course.

  buildJustificationFields(x: any): FormGroup {
    return new FormGroup({
      name: new FormControl(x.name),
      description: new FormControl(x.description),
      code: new FormControl(x.code),
    });
  }

The function above populates the fields already set in the create form function. However, initially this function was being called first to build the fields at the same time as populating them.

I think the issue is with the setValue line in the population function.

Any help appreciated. I have created this stackBlitz .

1.-First you need call to the function this. populateForm(); this. populateForm(); into the subcribe function -else don't exist this.form-. You see an error in console.

2.-SetValue is to give value -the argument should be an array of object with name,description and code, NOT a formGroup

f.get('justificationItems').setValue(model.justificationItems)

3.-But before use setValue you need be sure that the FormArray has the same elements that the array -else only give value to the first elements of the FormArray so you make some like

  //use a "getter" to simplify the functions
  get justificationArray(){
    return this.form.get('justificationItems') as FormArray
  }

    while (this.justification.controls.length>model.justificationItems.length)    
  this.deleteItem(0)

    while (this.justificationArray.controls.length<model.justificationItems.length)    
      this.addItem()

    this.justificationArray.setValue(model.justificationItems)

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