3

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

2 Answers 2

4

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/

Sign up to request clarification or add additional context in comments.

2 Comments

very concise solution. But this syntax is not very clear to me, especially .at(0) method?
Hey Thanks .. Yes Check this Docs out angular.io/docs/ts/latest/api/forms/index/FormArray-class.html On a form Array you have a Method to get at(index: number) : AbstractControl
1

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'
});

2 Comments

Hmm, but how I can get item by index. list[9] = [,,,,,,,,,] ?
Yeah, it isn't ideal. Accessing these via an index would be better. I tried that, but it was getting late, and I wanted to get this out. I may play with it more.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.