Bazinga777
Bazinga777

Reputation: 5281

Angular2/4 How to automatically update formArray size according to inserted data?

I have the following configuration for my form builder

 this.fb.group({
            id: [this.app.get('id'), []],
            tips: new FormArray([new FormControl('')]),
 })

I would like to update the size of tips, depending on the data that I am inserting into it during setValue() or patchValue(). If I have the following data

{
 id: 123,
 tips: [ 'Drink water', 'Exercise' ]
}

I would like the array to automatically expand. Does Angular have such a feature or do i have to check the size of the array and insert new controls into it ?

Upvotes: 3

Views: 1288

Answers (2)

Scott Ayers
Scott Ayers

Reputation: 143

I ran into a similar issue where I did not want to lose my Validators or valueChange observable.

The simplest solution is to:

  • Encapsulate your "tip" instantiation in a method to be reused
  • Use removeAt() and push() to match the incoming value's length
    setFormValue(newValues: TipList): void {
        const tipArray: FormArray = <FormArray>this.myForm.get('tips');

        // Remove controls in the list to match new value
        while (tipArray.length > newValues.tips.length) {
            tipArray.removeAt(0);
        }
        // Add controls in the list to match new value
        while (tipArray.length < newValues.tips.length) {
            tipArray.push(this.getNewTip());
        }

        // Finally set the incoming value
        this.myForm.setValue(newValues);
    }

    getNewTip(): FormControl {
        const tip: FormControl = new FormControl(''); // <- set validation here
        // Set other things like valueChange here
        return tip;
    }

You can see the working StackBlitz here

Upvotes: 0

AVJT82
AVJT82

Reputation: 73357

Let's see if I understood you correctly...

You want patch values you receive. An option would be to use setControl(), which replaces the existing tips FormArray.

myObject = {id: 123, tips: ['Drink water' , 'Exercise']}

And then do:

setValues() {
  this.myForm.setValue({
    id: this.obj.id,
  })
  // I like to inject 'FormBuilder' in constructor and use 'fb'
  this.myForm.setControl('tips', this.fb.array(this.obj.tips))
}

Upvotes: 3

Related Questions