Angular 4: setValue formBuilder empty array
Asked Answered
A

4

13

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?

Antiseptic answered 31/5, 2017 at 9:30 Comment(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.Monger
T
21

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! :)

Tailspin answered 31/5, 2017 at 10:12 Comment(3)
i think it should be control.controls.removeAt(i). Because the console.log(control) has a array with name controls otherwise you get the error "Cannot read property 'enabled' of null".Funiculate
Thanks. This was the only solution that worked in this whole page.Aestheticism
Instead of the for-loop, you can just do control.clear().Breath
I
10

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

Impracticable answered 1/8, 2017 at 17:27 Comment(2)
And we still do it like this in Angular 7Hanus
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() methodRecapitulation
F
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([]));
Fonz answered 22/2, 2018 at 22:50 Comment(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.Damned
P
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.

Pannonia answered 18/10, 2017 at 19:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.