khex
khex

Reputation: 2828

Change FormBuilder array items in nested forms

According to the API documentation the proper way to change nested values is to use method patchValue

myForm.patchValue({'key': {'subKey': 'newValue'}});

But how to change values in nested arrays like list of cars in this example below. How to get first item of list array an change model to Fiesta? Plunker

myForm.patchValue({'list': 0: {'model': 'Fiesta'}); is not working.

@Component({
  moduleId: __moduleName,
  selector: 'my-app',
  template: `<div><pre>{{ myForm.value | json }}</pre></div>`
})
export class AppComponent {

  public myForm: FormGroup;

  constructor(@Inject(FormBuilder) private _fb: FormBuilder) {

    this.myForm = this._fb.group({
      name: 'Cars',
      list:  this._fb.array([
        this.initCar(),
        this.initCar(),
        this.initCar()
      ]),
    });
    /** Change value Here **/
    this.myForm.patchValue({name: 'Automobile'});
  };

  initCar() {
    return this._fb.group({
      automaker: 'Ford',
      model:     'Fusion'
    });
  }
}

Plunker

Upvotes: 3

Views: 3235

Answers (2)

R. Richards
R. Richards

Reputation: 25161

Here is a way to access and patch a FormArray in Angular 2. I have modified your code to get this to work using your Plunk.

import { Inject, Component } from '@angular/core';
import { FormBuilder, FormArray }       from '@angular/forms';

@Component({
  moduleId: __moduleName,
  selector: 'my-app',
  template: `<div><pre>{{ myForm.value | json }}</pre></div>`
})
export class AppComponent {

  public myForm: FormGroup;

  constructor(@Inject(FormBuilder) private _fb: FormBuilder) {

    this.myForm = this._fb.group({
      name: 'Cars',
      list:  this._fb.array([
        this.initCar(),
        this.initCar(),
        this.initCar()
      ]),
    });

    this.myForm.patchValue({name: 'Automobile'});

    /** Make changes here ***/
    // access the array from the form
    var items = this.myForm.get('list');

    // change the first item
    items.patchValue([{
      model: 'Fiesta'
    }]);

    // change the second item (notice the comma in front of the array)
    items.patchValue([,
    {
      model: 'TLX',
      automaker: 'Acura'
    }]);

    // change the third item (notice the 2 commas in front of the array)
    items.patchValue([,,
    {
      model: 'Accord',
      automaker: 'Honda'
    }]);

  };

  initCar() {
    return this._fb.group({
      automaker: 'Ford',
      model:     'Fusion'
    });
  }

}

Output before:

{
  "name": "Automobile",
  "list": [
    {
      "automaker": "Ford",
      "model": "Fusion"
    },
    {
      "automaker": "Ford",
      "model": "Fusion"
    },
    {
      "automaker": "Ford",
      "model": "Fusion"
    }
  ]
}

Output after:

{
  "name": "Automobile",
  "list": [
    {
      "automaker": "Ford",
      "model": "Fiesta"
    },
    {
      "automaker": "Acura",
      "model": "TLX"
    },
    {
      "automaker": "Honda",
      "model": "Accord"
    }
  ]
}

EDIT: A better solution:

// access the array from the form
var items = this.myForm.get('list');

const item1 = (items).at(0);
// change the first item
item1.patchValue({model: 'Fiesta'});

// change the second item
const item2 = (items).at(1);
item2.patchValue({
  model: 'TLX',
  automaker: 'Acura'
});

// change the third item
const item3 = (items).at(2);
item3.patchValue({
  model: 'Accord',
  automaker: 'Honda'
});

Upvotes: 1

edumas000
edumas000

Reputation: 282

I did something similar not that long ago just add.

const patchV = (<FormArray>this.myForm.controls['list']).at(0) as FormArray;
patchV.patchValue({automaker: 'CoolCar', model: 'Bucket'})

Working Example [plunker]http://embed.plnkr.co/VWicnA/

Upvotes: 4

Related Questions