Liem
Liem

Reputation: 456

Angular - How to initiate FormArray from an existing array?

I would like to create an editable table with FormArray.

For this, I have the results attribute that is rendered in the table.

What's the proper way to initialize it with FormArray data?

results: Array;
tableForm: FormGroup;

ngOnInit(private fb: FormBuilder) {
  this.tableForm = this.fb.group({
    arrayForm: this.fb.array([])
  });
}

Upvotes: 7

Views: 13548

Answers (2)

user4676340
user4676340

Reputation:

A form array is a bundle of form controls (as a reminder, a form group is a form control).

In the following I will assume your results are model-related, such as

[
  { id: 1, title: 'title 1' },
  { id: 2, title: 'title 2' },
]

(If not, feel free to explain to me what the results are)

Since a form array must accept controls, you will have to map your results to comply with the signature.

You can do it with this :

ngOnInit(private fb: FormBuilder) {
 this.tableForm = this.fb.group({
   arrayForm: this.fb.array(this.results.map(r => this.fb.group(r)))
 });
}

With this, your form array will contain a form group, made of all the properties in your object.

Is this what you wanted or not ?

Upvotes: 11

Stavm
Stavm

Reputation: 8121

You can create an array based on the OBJECT(not an interface).

I actually wrote a small demo a few days ago:

our OBJECT (!):

 valueFromBackend = {
    propOne: 'X',
    propTwo: 'Y',
    propArray: [
      {
        objPropA: 'a',
        objPropB: 'b'
      },
      {
        objPropA: 'c',
        objPropB: 'd'
      },
      {
        objPropA: 'e',
        objPropB: 'f'
      }
    ]
  }

Component:

ngOnInit() {
    const count = this.valueFromBackend.propArray.length

    this.myForm = this.fb.group({
      propOne: '',
      propTwo: '',
      propArray: this.fb.array([...this.createItems(count)])
    });

    // dynamically set value
    this.myForm.setValue(this.valueFromBackend);
  }

  private createItem(): FormGroup {
    return this.fb.group({
      objPropA: '',
      objPropB: '',
    });
  }

  private createItems(count: number): FormGroup[] {
    const arr = [];
    for (let i = 0; i < count; i++) {
      arr.push(this.createItem());
    }
    return arr;
  }

HTML:

<form [formGroup]="myForm">
    <div formArrayName="propArray" *ngFor="let item of myForm.get('propArray').controls; let i = index;">
        <div [formGroupName]="i">
            <input formControlName="objPropA" placeholder="Item name">
      <input formControlName="objPropB" placeholder="Item description">
  </div>
  </div>
</form>

Upvotes: 4

Related Questions