10

I have such reactive form:

constructor(...){
  this.form = this.formBuilder.group({
    name: ['', Validators.compose([Validators.required, Validators.maxLength(50)])],
    memes: this.formBuilder.array([
      this.initMemes('TrollFace')
    ])
  });
}

initMemes (name?) {
  return this.formBuilder.group({
    id: [''], name: [name]
  });
}

later i can add some more memes:

addMemes () {
  const control = <FormArray>this.form.controls['memes'];
  control.push(this.initMemes('anyName'));
}

and then if i get form values i get:

this.form.controls['memes'].value - here i have array

But there is a case, when i need this this.form.controls['memes'].value to set to an empty array, how is it possible to do?

If i set it this way:

this.form.controls['memes'].setValue([])

I got error: Must supply a value for form control at index: 0.

what i do wrong?

brabertaser19
  • 5,384
  • 14
  • 69
  • 164
  • 1
    For anyone who reads this: I struggled with this error after following a tutorial about FormArray. The solution is simple, just init the FormArray with a pair of empty square brackets []: this.formBuilder.array([ ]). I don't know what the function call in there is supposed to do, I just know it gives that error. – Jette Aug 28 '18 at 11:40

4 Answers4

15

EDIT:

As of newer versions, Angular now supports clearing a FormArray with clear():

(<FormArray>this.form.get('memes')).clear();

ORIGINAL:

Tried a few things:reset(),setControl(), but the following was the only solution I found to work that actually resets the whole array to [], other options worked, but they left the formgroups in place, just emptied the values.

So how I got it to work, was to iterate the form array and delete each form group with that particular index in the loop:

const control = <FormArray>this.form.controls['memes'];

for(let i = control.length-1; i >= 0; i--) {
  control.removeAt(i)
}

If there is a better way, I'm open for suggestions! :)

AJT82
  • 60,574
  • 21
  • 115
  • 147
8

Try this.myForm.controls['myFormArray'] = this.formBuilder.array([]); with formBuilder service instantiated in your constructor.

Jacob Kochocki
  • 240
  • 1
  • 5
  • 13
  • 1
    And we still do it like this in Angular 7 – Stefan Falk Mar 09 '19 at 10:16
  • 1
    Doing this leaves the parent form invalid if the formArray had an invalid control before clearing it like this. The best way for Ng<8 is to use removeAt in a loop. For Angular 8+, use FormArray.clear() method – mlakhara Jun 05 '19 at 17:32
5

FORM

this.form = this._formB.group({
    blocks: this._formB.array([])
});

1st method

let fArray = <FormArray>this.form.controls['blocks'];
while (fArray.length !== 0) {
  fArray.removeAt(0)
}

2nd method

this.form.setControl('blocks', this._formB.array([]));
  • 1
    Please add some explanation to your answer, this helps to OP as well as to other people that might end up here while searching for similar problem. – FilipRistic Feb 22 '18 at 23:09
1

I was having a similar issue, where I would get said error after updating my form, and after a bunch of investigation and failed experimentation I found that this.myForm.updateValueAndValidity finally did the trick.

Arun Vinoth
  • 20,360
  • 14
  • 48
  • 135
Sam
  • 11
  • 1