Search code examples
javascriptangularformsformarrayformgroups

Angular Reactive Form with dynamic fields


I'm currently battling with Angular form array.

I have a form in which I add the fields dynamically.

I have created the form object:

this.otherDataForm = this.fb.group({
});

I add the dynamic fields like this:

addField(field: CustomFormField): void {
    this.otherDataForm.addControl(id_campo, new FormControl('', Validators.required));
}

I loop through those fields:

<form *ngIf="selectedProfile" [formGroup]="otherDataForm">
      <div class="mb-3" *ngFor="let field of fields; let i = index">
           <label>{{field.descripcion}}</label>
           <input class="form-control" [formControlName]="field.id_campo" type="number">
      </div>
</form>

But I can't seem to get control of the errors of each field to show a validation message if the field is required.

Anyone can help me with this one? Maybe there is a better way to do this.


Solution

  • well, I feel more comfortable using directly the constructor of formControl and formGroup

    fields=[{id:'one',label : 'one',value:1},{id:'two',label : 'two',value:2}]
    form=new FormGroup({})
    ngOnInit()
    {
       this.fields.forEach(x=>{
        this.form.addControl(x.id,new FormControl(x.value,Validators.Required))
       })
    }
    
    <form [formGroup]="form">
        <div *ngFor="let field of fields">
            <input [formControlName]="field.id">
            <div class="error" *ngIf="form.get(field.id).touched &&
                form.get(field.id).invalid">Required</div>
        </div>
    </form>
    {{form?.value|json}}
    

    But you can use directily [formControl] in the input

    <form [formGroup]="form">
        <div *ngFor="let field of fields">
        <label>{{field.label}}</label>
            <input [formControl]="form.get(field.id)">
            <div class="error" *ngIf="form.get(field.id).touched && 
                 form.get(field.id).invalid">Required</div>
        </div>
    </form>
    

    Even, you can iterate over form.controls|keyvalue

    <form [formGroup]="form">
        <div *ngFor="let control of form.controls |keyvalue;let i=index">
        <label>{{fields[i].label}}</label>
        <input [formControl]="control.value">
            <div class="error" *ngIf="control.value.touched && 
                   control.value.invalid">Required</div>
        </div>
    </form>
    

    see stackblitz