Search code examples
angularangular-materialangular-reactive-forms

angular reactive FormArray and material - control.setValidators is not a function


I have an angular material table in a reactive form, and I need it to show a number of inputs for every row. I can't know the number of rows in advance. Thus, I use FormArray and populate it with FormGroup which in turn contains FormControl's.

Here's the StackBlitz demo.

If you run it you'll see the error:

Error: control.setValidators is not a function

It's caused by the filter input which is not part of FormArray. If I comment it out, the error disappears. But what is the problem with a simple FormControl here?

Can anyone please explain how to fix it? Is this a bug?


Solution

  • Ok, the problem is with understanding of how FormArray works.

    FormArray does not use (and can't use) names to reference its elements (it is an array, there are only indexes), so you may only refer to FormControls/FormGroup's within that array by its index.

    In my example the filter control lies within FormArray called products. First, we need to create filter FormControl and add it to the array:

    this.products.push(new FormControl(null, [Validators.maxLength(20)]), {
          emitEvent: false,
        });
    
    this.filterFld = this.products.at(0) as FormControl;
    

    Secondly, we can't use formControlName to associate this newly created control with its input by name, as the control is not part of any FormGroup (it's part of a FormArray). So we have to use formControl directive insead to associate it with its input by reference:

    <input
                  matInput
                  [formControl]="filterFld"
                  placeholder="any text"
                  maxlength="20"
                />
    

    Here's the fixed stackblitz.