anilkumarggk
anilkumarggk

Reputation: 186

Angular template driven form: input "component" not binding to form

I'm trying to generate form fields dynamically based on some JSON object(config). This said config object contains all the attribute values required for constructing form fields(ex: label, type, placeholder etc).

Setup

In my parent component: I have a form, under which I have an ngFor, iterating over the config object, trying to generate the fields.

<form #dynamicForm="ngForm">
  <div *ngFor="let field of formFields">    <!-- formFields is the config object -->
    <app-form-field [props]="field" [formData]="formData"></app-form-field>
  </div>
  <button [disabled]="!dynamicForm.form.valid">Submit</button>
</form>

To avoid clogging the parent component, I have created a generic <form-field> component, which takes all the field attributes(as props) and a reference object(to bind the field's value).

<div *ngIf="props.type === 'text'">         <!-- One div for each input type -->
  <label [for]="props.id">{{ props.label }}</label>
  <input
    #field="ngModel"
    [id]="props.id"
    [type]="props.type"
    [attr.name]="props.name"
    [placeholder]="props.placeholder"
    [(ngModel)]="formModel[props['apiDataKey']]"
    [required]="props.isRequired"
    [disabled]="props.isDisabled"
  >
</div>

<!-- Other input types here -->

Question

The form tag contains a local reference #dynamicForm="ngForm" -> which never seems to update.

While the individual field validations work perfectly fine, the main form(dynamicForm.value) seems to:

I've created a demo on stackblitz here: https://stackblitz.com/edit/angular-ivy-nvm4hd?file=src/app/app.component.html

PS: I'm pretty new to angular2+, and can't seem to figure out what it is that I'm missing.

Thanks a bunch in advance 🙂

Upvotes: 2

Views: 865

Answers (1)

Siddhant
Siddhant

Reputation: 3171

In the Child Component viewProviders array, we can provide ControlContainer to use existing NgForm instance:

@Component({
 ...,
 viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
export class FormFieldComponent implements OnInit {
 ...
}

Upvotes: 2

Related Questions