7

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.

jenesuispastom
  • 129
  • 1
  • 1
  • 7
  • How is `[formControlName]="field.id_campo"` dynamic? – Nicholas K Jan 27 '20 at 16:54
  • what is `id_campo` and where is it set, please create a stackblitz to be able help you better – Reza Jan 27 '20 at 16:57
  • Think that a formGroup is only a group of FormControls. To access to a formControl of a formGroup you use nameOfForm.get('nameOfField'), so you can use `otherDataForm.get(field.id_campo)` to get the formControl, so `otherDataForm.get(field.id_campo).valid` give you if is valid, `otherDataForm.get(field.id_campo).errors` give you the errors... even you can use in your input `` – Eliseo Jan 27 '20 at 17:36
  • @Eliseo I've tried this but this doesn't work, it's seems like the ngfor works apart of the form. – jenesuispastom Jan 27 '20 at 18:09
  • @NicholasK Well, at least that appends the property "field.id_campo" as a name for each field. – jenesuispastom Jan 27 '20 at 18:10
  • The value of the form when I submit it, it returns this, that it's what I'm expecting. value: 1: "" 14: "" 29: "asd" 43: "1636" 57: "asd" 72: 123 87: "sad" 102: "asfa" 116: "asfa" 154: "" – jenesuispastom Jan 27 '20 at 18:11
  • you has a mistake in your function addField. You use inside id_campo, but you don't pass as argument. I left a stackblitz in the answer with differents ways to manage a FormControl. tip: it's usefull add in the .html for check some like `{{form?.value|json}}` to see the value of the form – Eliseo Jan 27 '20 at 20:10

1 Answers1

18

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

Moin Memon
  • 94
  • 1
  • 6
Eliseo
  • 50,109
  • 4
  • 29
  • 67